我现在已经为一个简单的问题摆弄了整整两天。
我有一个包含 Product 实体和 ProductLocationHistory 实体的数据库。ProductLocationHistory 具有对 Storehouse、Contact 或 Relation 的引用。每次移动产品时,它都会获得一个新条目,因此可以追踪产品的过去。因此,当前位置是由 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();
这些都是目前有产品的仓库。
当然,在我需要确定产品的当前位置时,将其写在代码中是非常不方便的。由于可能存在一致性问题,我认为完全不希望引用 Product 中的当前 ProductLocationHistory。我更喜欢这样的东西:
Product.ProductLocationHistories.Current();
所以我尝试了:
public static ProductLocationHistory Current(this EntitySet<ProductLocationHistory> plhs)
{
return plhs.SingleOrDefault(plh => plh.DateCreation == plhs.Max(grp => grp.DateCreation));
}
这不适用于可查询,因为我得到“当前不支持对 sql 的翻译”,并且由于 Product 和 ProductLocationHistory 的组合通常是查询的“开始”,我想保持 IQueryable 而不是立即到 IEnumerable 并进行查询为每个产品确定当前位置!更不用说之后的其他内容了......经常使用任何实体的当前日志条目,只要 .Current() 函数工作并保持可查询,它的复杂程度并不重要。我曾希望我的 .Current(...) 函数能够工作,因为底层代码是可查询的,但我仍然遇到异常。当代码像第一个示例中那样内联时,我没有得到异常。
我已经经历了诸如 Func、ProductLocationHistory>> 以及 Expression<...> 之类的可能性,但我找不到我正在寻找的示例。Product.CurrentProductLocationHistory() 类型的解决方案可能会更好。绝对最佳的解决方案将更加通用,形式如下:
Current<T> (IQueryable<T> collection, string field) { return entity with max field of collection }
非常感谢您的帮助,我已经尝试了很长时间,并且我确信它必须是可能的,因为 LINQ 本身的内部功能 - Any,First,Count,Max - 如果需要也可以查询。
更新
目前,以下工作:
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() 所以我的任务继续。
已经感谢基里尔了!这是我第一次看到 C# 代码翻译成 SQL!朝着正确方向迈出的一大步!