简化要在谓词中使用的此属性

时间:2012-03-09 00:15:02

标签: c# silverlight-4.0 entity-framework-4 linq-to-entities wcf-ria-services

我有很多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)

这样的内容

2 个答案:

答案 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);
    }
}   

这是要走的路吗?此更改是否存在性能问题?