我一直在摆弄整整两天,现在有一个简单的问题。IQueryable的扩展没有转换到SQL
我有一个产品实体和ProductLocationHistory实体的数据库。 ProductLocationHistory具有对仓库,联系人或关系的引用。每次产品移动时,都会得到一个新条目,以便跟踪产品的过去。因此,当前位置是由ProductLocationHistory的DateCreation字段确定的最后一个条目。
一个例子:
var storehousesWithBorrowedItems = productService.GetAllProducts()
.Select(p => p.ProductLocationHistories
.SingleOrDefault(plh => plh.DateCreation == p.ProductLocationHistories.Max(grp => grp.DateCreation)))
.Select(plh => plh.Storehouse)
.Distinct();
这些是目前有一个产品的所有仓库。
当然,我需要确定产品的当前位置时,将代码编写出来非常不方便。由于可能出现的一致性问题,我认为对产品中当前的ProductLocationHistory的引用完全是不受欢迎的。我喜欢这样的:
Product.ProductLocationHistories.Current();
所以,我想:
public static ProductLocationHistory Current(this EntitySet<ProductLocationHistory> plhs)
{
return plhs.SingleOrDefault(plh => plh.DateCreation == plhs.Max(grp => grp.DateCreation));
}
这并不在可查询的工作,我得到一个“当前没有支持转换为SQL”,由于产品组合而ProductLocationHistory通常是查询的“开始”,我希望保留IQueryable而不是立即对IEnumerable进行查询,并为每个产品查询以确定当前位置!更别说以后还有其他什么东西......任何实体的当前日志条目经常被使用,只要它能够工作并保持可查询,.Current()函数的复杂程度就不重要了。我希望我的.Current(...)函数可以工作,因为底层代码是可查询的,但我仍然遇到异常。当代码与第一个示例中一样内联时,我没有得到异常。
我已经经历过像Func,ProductLocationHistory >>和表达式< ...>的可能性...>,但是我找不到我正在寻找的示例。类型Product.CurrentProductLocationHistory()的解决方案可能会更好。绝对最好的解决办法是更通用的形式:
Current<T> (IQueryable<T> collection, string field) { return entity with max field of collection }
帮助将不胜感激,我一直在尝试这个很长一段时间,我敢肯定那一定是可能的,因为内部功能LINQ本身 - 任何,首先,计数,最大 - 如果需要也可以保持查询。
更新
目前,以下工作:
Expression<Func<Product, ProductLocationHistory>> expression = IQueryable.Current(null);
var ken = productService.GetAllProducts()
.Where(p => p.OnLoan)
.Select(expression)
.Where(plh => plh.Storehouse != null)
.Select(plh => plh.Storehouse)
.Distinct();
public static Expression<Func<Product, ProductLocationHistory>> Current(this EntitySet<ProductLocationHistory> productLocationHistories)
{
Expression<Func<Product, ProductLocationHistory>> expression = p => p.ProductLocationHistories
.SingleOrDefault(plh => plh.DateCreation == p.ProductLocationHistories.Max(plhs => plhs.DateCreation));
return expression;
}
朝着正确方向迈出的一步,但我还没有完全满意。我希望能够使用p.ProductLocationHistories()。Current()来继续我的追求。
感谢Kirill!这是我第一次将C#代码翻译成SQL!朝着正确的方向迈出了一步!
有了这个扩展方法,你可以* *调用.Current()如果我不是误。你可以展示你想使用的调用约定的示例吗?此外,使用'OrderByDescending(pld => pld.DateCreation).FirstOrDefault()'比使用'SingleOrDefault'查询max要快很多。 – jessehouwing
我会尽快升级到ASP.NET 4.5,然后尝试解决方案[link](http://stackoverflow.com/questions/10826275/queryable-extension-method-for-linq2entities)。目前我们正在收购Visual Studio 2012.之后我可能会更新此问题。 – Paul1977