我有一个User
类,其中包含导航属性Settings
和一个只读属性IsVisibleInApp
。
目前此代码有效:
var users = context.Users.Include(x => x.Settings)
.Where(x => x.Settings.IsApproved && x.Settings.IsAvailable && x.UserType == 2);
但是我必须经常使用这些检查,所以我尝试使用一个属性,并在运行时将Settings
变为null。
这是我的代码。
public bool IsVisibleInApp
{
get
{
return this.Settings.IsApproved && this.Settings.IsAvailable && this.UserType == 2;
}
}
...
...
void SomeMethod(){
var users = context.Users.Include(x => x.Settings)
.Where(x => x.IsVisibleInApp).ToList();
我可以看到外键this.SettingsID
是有效值。我猜属性/方法不能在Where
上的DBSets
子句中使用,因为它们会被转换为SQL?
但肯定有一种解决方法......或者我必须首先执行.ToList()
然后再使用.Where
调用,但这意味着从数据库中提取所有行很多额外的工作......
答案 0 :(得分:3)
你不能按照你想要的方式去做(EF不会进入你的属性getter并查看你在那里做的事情),但你可以通过将它包装在静态表达式中来减少代码重复:
public static Expression<Func<User, bool>> IsVisibleInAppExpression = x =>
x.Settings.IsApproved && x.Settings.IsAvailable && x.UserType == 2;
然后像这样使用:
var users = context.Users.Include(x => x.Settings)
.Where(User.IsVisibleInAppExpression).ToList();
或者通过创建扩展方法:
public static class Extensions {
public static IQueryable<User> VisibleInAppOnly(this IQueryable<User> query)
{
return query.Where(x =>
x.Settings.IsApproved && x.Settings.IsAvailable && x.UserType == 2);
}
}
使用这样:
var users = context.Users.Include(x => x.Settings).VisibleInAppOnly();