2015-11-17 73 views
1

我很努力地将sql语句转换成Linq。Linq多重连接 - 结果太多

我得到的结果太多,无法计算出正确的语法应该是什么。

这是SQL:

SELECT   
    Client_Details_Legacy.FullName, 
    Client_Details_Legacy.AddressLine1, 
    Client_Details_Legacy.AddressLine2, 
    Client_Details_Legacy.AddressLine3, 
    Policy_Property.PolicyNumber, 
    Policy_Property.CoverTo, 
    Clients.Id 
FROM    
    Clients 
    INNER JOIN Policy_Property 
     ON Clients.Id = Policy_Property.Client_Id 
    INNER JOIN Client_Details_Legacy 
     ON Clients.Client_Details_Legacy_Id = Client_Details_Legacy.Id 
WHERE   
    (Policy_Property.CoverTo >= CONVERT(DATETIME, '2015-12-01 00:00:00', 102)) 
    AND (Policy_Property.CoverTo <= CONVERT(DATETIME, '2015-12-31 00:00:00', 102)) 
ORDER BY 
    Clients.Id 

这是接近我设法让我的LINQ的声明,但它返回更多的行比它应该是。

我怀疑它的东西做加盟,但我似乎无法得到正确的语法:

var query = from clients in db.Clients 
         .Include("Client_Details_Legacy") 
         .Include("Policies_Property") 
      where clients.Client_Details_Legacy.Country.Code == countryCode 
        && clients.Policies_Property.Any(x => x.CoverTo >= CoverToStart 
                 && x.CoverTo <= CoverToEnd) 
      select clients; 

return query.ToList(); 

这是我的模型......

public class Client 
{ 
    public int Id { get; set; } 
    [Index] 
    [MaxLength(50)] 
    public string ClientNumber_Legacy { get; set; } 
    [Index] 
    [MaxLength(50)] 
    public string ClientNuber_Websure { get; set; } 
    public Client_Details_Enhanced Client_Details_Enhanced { get; set; } 
    public Client_Details_Legacy Client_Details_Legacy { get; set; } 
    public Client_Details_Websure Client_Details_Websure { get; set; } 
    public List<Policy_Motor> Policies_Motors { get; set; } 
    public List<Policy_Property> Policies_Property { get; set; } 
} 

public class Policy_Property 
{ 
    [Key] 
    [MaxLength(50)] 
    public string PolicyNumber { get; set; } 
    public Policy_Property_Details_Legacy Policy_Property_Details_Legacy { get; set; } 
    public Policy_Property_Details_Enhanced Policy_Property_Details_Enhanced { get; set; } 
    public DateTime CoverFrom { get; set; } 
    public DateTime CoverTo { get; set; } 
    public List<Insured_Property> Insured_Properties { get; set; } 
} 

public class Client_Details_Legacy 
{ 
    public int Id { get; set; } 

    public ws_lookup_ClientType ClientType { get; set; } 

    [DisplayName("Title")] 
    public ws_lookup_Title Title { get; set; } 

    [Index] 
    [DisplayName("Full Name")] 
    [MaxLength(250)] 
    public string FullName { get; set; } 

    public string NationalIdNumber { get; set; } 
    public string EmailAddress { get; set; } 
    [DisplayName("Address Line 1")] 
    [MaxLength(250)] 
    public string AddressLine1 { get; set; } 

    [DisplayName("Address Line 2")] 
    [MaxLength(250)] 
    public string AddressLine2 { get; set; } 

    [DisplayName("Address Line 3")] 
    [MaxLength(250)] 
    public string AddressLine3 { get; set; } 

    [DisplayName("Address Line 4")] 
    [MaxLength(250)] 
    public string AddressLine4 { get; set; } 

    [DisplayName("Country")] 
    public ws_lookup_Country Country { get; set; } 

    [DisplayName("Parish")] 
    public ws_lookup_Parish Parish { get; set; } 

    [DisplayName("Home Telephone Number")] 
    [MaxLength(250)] 
    public string HomeTelephoneNumber { get; set; } 

    [DisplayName("Work Telephone Number")] 
    [MaxLength(250)] 
    public string WorkTelephoneNumber { get; set; } 

    [DisplayFormat(DataFormatString = "{0:dd MMM yyyy}")] 
    [DisplayName("Date of Birth")] 
    public DateTime? DateOfBirth { get; set; } 

    [DisplayName("Gender")] 
    public ws_lookup_Gender Gender { get; set; } 

    [DisplayName("Loyalty Card")] 
    [MaxLength(50)] 
    public string LoyaltyCard { get; set; } 

    [DisplayName("Occupation")] 
    public ws_lookup_Occupation Occupation { get; set; } 
} 

谁能帮我找到了什么我做错了吗?

+0

为什么会出现在LINQ尝试的国家代码,而不是在原来的SQL? –

回答

3

部分原因是,您的查询,而你试图返回特定的客户端返回的某些数据。但这不会起作用,因为客户与多种政策相关联,但您只对特定政策感兴趣。以下应该给出与SQL相同的结果。

var query = from client in db.Clients 
      from policy in client.Policies_Property 
      where policy.CovertTo >= ConvertToStart && policy.ConverTo <= ConverToEnd 
        && client.Client_Details_Legacy != null 
      select new 
      { 
       client.Client_Details_Legacy.FullName, 
       client.Client_Details_Legacy.AddressLine1, 
       client.Client_Details_Legacy.AddressLine2, 
       client.Client_Details_Legacy.AddressLine3, 
       policy.PolicyNumber, 
       policy.CoverTo, 
       client.Id 
      }; 

注意我离开了client.Client_Details_Legacy.Country.Code == countryCode因为这是未出现在SQL。

+0

如果客户端没有匹配的ClientDetailLegacy - 在原来它会被过滤,但不会被过滤,因为我读这个代码.. –

+0

@DavidB好点。固定。 – juharr

0

我认为这里的线是问题:

clients.Policies_Property.Any(x => x.CoverTo >= CoverToStart && x.CoverTo <= CoverToEnd) 

采用Any将返回所有记录,如果1成立,而不是只返回满足该条款的行。

Enumerable.Any:确定序列中的任何元素是否满足条件。

,而不必查看数据或测试手段,你可以尝试...问题的

where clients.Client_Details_Legacy.Country.Code == countryCode 
       && (clients.Policies_Property.CoverTo >= CoverToStart && 
        clients.Policies_Property.CoverTo <= CoverToEnd) 
+0

我同意这是问题所在,但是您还没有提出解决方案,因此作为评论会比答案更好。 – juharr

+0

@juharr,我只是打字:) – christiandev

+0

'Policies_Property'是一个'List ',所以它不会有'CovertTo'属性。 – juharr

1

你的SQL语句,可以很容易地转换为LINQ是这样的:

var query = from clients in db.Clients 
         join cdl in db.Client_Details_Legacy on cdl.Id = clients.Client_Details_Legacy_Id 
         join pp in db.Policies_Property on pp.Client_Id = clients.Id 
      where pp.CoverTo >= CoverToStart && pp.CoverTo <= CoverToEnd 
      select new { 
       FullName = cdl.FullName, 
       AddressLine1 = cdl.AddressLine1, 
       AddressLine2 = cdl.AddressLine2, 
       AddressLine3 = cdl.AddressLine3, 
       PolicyNumber = pp.PolicyNumber, 
       CoverTo = pp.CoverTo, 
       Id = clients.Id 
       }; 
return query.OrderBy(q => q.Id).ToList(); 
+0

我建议您阅读[不要使用Linq的加入。导航!](https://coding.abel.nu/2012/06/dont-use-linqs-join-navigate/) – juharr

+0

那么,使用导航属性并不是什么新东西,但也不一定是更好的方式来翻译SQL查询。想象一下,无论出于何种原因,这些实体都没有导航属性,那么如何进行LINQ查询呢? – Ramanagom

+0

然后你会使用连接,但重点是导航属性是可取的,如果存在,因为它们在这种情况下。 – juharr