如何使用基于复杂计算数据的子句正确生成LINQ查询

时间:2014-05-02 21:05:58

标签: c# sql linq entity-framework

我对LINQ to Entities和LINQ to SQL有着非常丰富的经验,但这个问题让我头脑发热。

我需要一些关于如何成功创建干净的LINQ to Entities查询的指导,当它具有基于计算列的条件子句时,以及将数据投影到对象中时,还需要使用该计算列。

预计结果类如下:

public class FilterClientsResult
{
    public enum ClientType
    {
        ALL,
        LIST,
        VIP
    }

    public int ClientId { get; set; }        

    public string Document { get; set; }

    public string Email { get; set; }

    public string LastName { get; set; }

    public string Name { get; set; }

    public ClientType Type { get; set; }

    public int Visits { get; set; }
}

然后数据来自主要来源和3个免费来源。

主要来源是客户实体,在其所有属性中,它具有所有预计属性,但最后2个(类型和访问)除外

其他来源是:

Subscription,其中1 Client可以包含多个Subscription

ClientAccess,其中1 Subscription可以包含多个ClientAccess

GuestListClient,其中1 Client可以包含多个GuestListClient

ClientType Type与[{1}}和FilterClientsResult.ClientType.ALL实体相关时,Client属性设置为ClientAccess

GuestListClient仅与FilterClientsResult.ClientType.VIP个实体相关时,它设置为ClientClientAccessFilterClientsResult.ClientType.LIST仅与Client相关时实体。

然后GuestListClient属性设置为与Visits相关的ClientAccessGuestListClient个实体的总和。

所以我需要的查询应该能够按Client过滤客户端,但也可以预测FilterClientsResult.ClientType

我还需要按FilterClientsResult.ClientType范围进行过滤,但也需要预测Visits值。

那么,构建像

这样的查询的最佳方法是什么

1 个答案:

答案 0 :(得分:0)

这最适合使用查询语法,使用let关键字将中间结果存储为变量:

from c in Clients
let vipCount = c.Subscriptions.SelectMany(s => s.ClientAccesses).Count()
let listCount = c.GuestListClients.Count()
select new FilterClientsResult {
        c.ClientId,
        ...
        Type = vipCount > 0 ? listCount > 0 ? ClientType.ALL 
                                            : ClientType.VIP 
                            : listCount == 0 ? 0 
                                             : ClientType.LIST,
        Visits  = vipCount + listCount
    }

(未检查语法)

请注意,EF必须知道ClientType枚举,否则您首先必须预测Typeint所需的属性。然后,在AsEnumerable()之后,将int转换为枚举。

另外请注意,当两个计数均为0时,存在一个优柔寡断的值。