我有很多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)
答案 0 :(得分:1)
提供此功能的一种非常简单的方法是使用扩展方法。
尝试这样的事情:
public static class AccountEx
{
public static IQueryable<Account> WhereIsRootAccount(
this IQueryable<Account> source)
{
return source.Where(acc => acc.ParentId == 0);
}
}
然后,您将使用.Where(acc => acc.ParentId == 0)
替换.WhereIsRootAccount()
的每次使用。
这种方法的优点是它可以与EF一起使用,它提供了一种流畅的查询root帐户的方法。如果您需要修改root帐户的定义,您也只有一个地方可以进行更改。并且它不会使用不必要的代码污染您的Account
类。
我希望这会有所帮助。
根据您的评论,试试这个:
public static class AccountEx
{
public static EntityQuery<Account> WhereIsRootAccount(
this EntityQuery<Account> source)
{
return source.Where(acc => acc.ParentId == 0);
}
}
由于Where
支持EntityQuery<>
,因此它仍然可以正常工作。
答案 1 :(得分:0)
这是我找到的东西,但我想知道是否有更好的事情要做 我理解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);
}
}
这是要走的路吗?此更改是否存在性能问题?