将此属性简化为在谓词中使用
本文关键字:谓词 属性 | 更新日期: 2023-09-27 18:27:16
我有很多Accounts
,每个帐户也可以有子帐户。因此,我知道帐户是否为root的方法要归功于ParentId
属性中的值
所以我的代码在很多地方都有这样的东西:.Where(acc => acc.ParentId == 0)
,所以我想创建一个看起来像这样的属性:
public bool IsRootAccount
{
return a.ParentId == 0;
}
它似乎可以工作,它可以编译,但当运行时,我会得到以下异常:
Load operation failed for query 'GetAccounts'. The specified type member 'IsRootAccount' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.
有没有一种简单的方法可以实现我想要的?
我还考虑过创建一些东西,让它在没有运气的情况下返回Expression<Func<Account, bool>>
。
编辑:我对IsRootAccount
属性的尝试是为了使用类似于.Where(acc => acc.IsRootAccount)
的东西
提供此功能的一种非常简单的方法是使用扩展方法。
试试这样的东西:
public static class AccountEx
{
public static IQueryable<Account> WhereIsRootAccount(
this IQueryable<Account> source)
{
return source.Where(acc => acc.ParentId == 0);
}
}
然后,您将用.WhereIsRootAccount()
替换.Where(acc => acc.ParentId == 0)
的每次使用。
这种方法的优点是它可以与EF一起使用,并且它提供了一种流畅的方式来查询您的根帐户。如果你需要修改根帐户的定义,你也只有一个地方可以进行更改。而且它不会用不必要的代码污染Account
类。
我希望这能有所帮助。
根据你的评论,试试这个:
public static class AccountEx
{
public static EntityQuery<Account> WhereIsRootAccount(
this EntityQuery<Account> source)
{
return source.Where(acc => acc.ParentId == 0);
}
}
由于EntityQuery<>
支持Where
,因此它应该仍然可以正常工作。
我发现了一些东西,但我想看看是否还有更好的办法。
我知道EF不知道如何将我的谓词转换为SQL,因为我的属性。所以我不能这样做:
Context.Load(Context.GetAccountsQuery().Where(acc => acc.IsRootAccount), ParentAccountsArrived, null);
但一旦结果从服务器返回,我确实可以用我的属性进行过滤:
public void LoadParentAccounts()
{
Context.Load(Context.GetAccountsQuery(), ParentAccountsArrived, null);
}
void ParentAccountsArrived(LoadOperation<Account> lo)
{
foreach (var account in lo.Entities.Where(acc => acc.IsRootAccount))
{
ParentAccounts.Add(account.Name);
}
}
这是要走的路吗?此更改是否存在性能问题?