【发布时间】:2016-05-18 04:53:01
【问题描述】:
我正在尝试在与 EF 一起使用的 Linq Select 中使用自定义函数。 我想将 tblMitarbeiter 的每一项投影到一个在给定日期有效的 tblMitarbeiterPersonalkostenstelleHistories 上。 这应该使用扩展方法来完成,这样我就不会重复自己;) 我只能在直接在 DbSet 上使用它时才能让它工作,而不是在 Select 内。
我如何教 EF 识别我的方法 (3.),就像我将它写出来 (1.) 一样?
void Main()
{
var date = DateTime.Now;
// 1. works, returns IEnumerable<tblMitarbeiterPersonalkostenstelleHistories>
tblMitarbeiters
.Select(m => m.tblMitarbeiterPersonalkostenstelleHistories.Where(p => p.ZuordnungGültigAb <= date).OrderByDescending(p => p.ZuordnungGültigAb).FirstOrDefault())
.Dump();
// 2. works, returns one tblMitarbeiterPersonalkostenstelleHistories
tblMitarbeiterPersonalkostenstelleHistories
.GetValidItemForDate(p => p.ZuordnungGültigAb, date)
.Dump();
// 3. throws NotSupportedException
tblMitarbeiters
.Select(m => m.tblMitarbeiterPersonalkostenstelleHistories.GetValidItemForDate(p => p.ZuordnungGültigAb, date))
.Dump();
// 4. throws NotSupportedException
tblMitarbeiters
.Select(m => m.tblMitarbeiterPersonalkostenstelleHistories.AsQueryable().GetValidItemForDate(p => p.ZuordnungGültigAb, date))
.Dump();
}
public static class QueryableExtensions
{
public static T GetValidItemForDate<T>(this IQueryable<T> source, Expression<Func<T, DateTime>> selector, DateTime date)
{
var dateAccessor = Expression.Lambda<Func<T, DateTime>>(Expression.Constant(date), selector.Parameters);
var lessThanOrEqual = Expression.LessThanOrEqual(selector.Body, dateAccessor.Body);
var lambda = Expression.Lambda<Func<T, bool>>(lessThanOrEqual, selector.Parameters);
return source.Where(lambda).OrderByDescending(selector).FirstOrDefault();
}
public static T GetValidItemForDate<T>(this IEnumerable<T> source, Func<T, DateTime> selector, DateTime date) =>
source.Where(i => selector(i) <= date).OrderByDescending(selector).FirstOrDefault();
}
【问题讨论】:
-
稳健方式 - 在您的
Select之前使用自定义方法调用ToList()。它有效,但我不推荐它。 -
我想在服务器上,而不是在内存中。
ToList()要么需要包含(性能不佳),要么需要大量延迟加载(性能更差) -
嗯,有 SqlFunctions 可以在 IQueryable 内部调用(在数据库端),但如果你想要更多,你应该使用存储过程或将其加载到内存中。
-
我的方法已经不能被分解成EF(1.)能识别的简单linq函数,所以不需要SqlFunctions。
标签: c# entity-framework linq extension-methods