SQL到Linq到实体的转换

SQL到Linq到实体的转换,sql,linq-to-entities,Sql,Linq To Entities,SQL请求: DECLARE @search varchar(20) set @search = '%a%' Select distinct top (500) Customer.Number,Contact.name, Address.StreetAddress, Phone.Number, Customer.Type from Customer left join dbo.Address on dbo.Customer.

SQL请求:

DECLARE @search varchar(20)
set @search = '%a%'

Select distinct top (500) 
    Customer.Number,Contact.name, Address.StreetAddress, Phone.Number, 
    Customer.Type               
from 
    Customer
left join 
    dbo.Address on dbo.Customer.ContactId  = dbo.Address.ContactId
left join 
    dbo.Contact on dbo.Customer.ContactId  = dbo.Contact.Id
left join 
    dbo.Phone on dbo.Customer.ContactId  = dbo.Phone.ContactId 
              and Phone.Sequence = 1
where 
    Customer.IsActive = 1 
    and Customer.ContactId 
        in (--Primary Contact
            SELECT  Customer.ContactId
            FROM dbo.Customer
            INNER JOIN dbo.Contact ON dbo.Contact.id = dbo.Customer.ContactId
            LEFT JOIN dbo.Email ON dbo.Customer.ContactId  = dbo.Email.ContactId
            LEFT JOIN dbo.Phone ON dbo.Customer.ContactId  = dbo.Phone.ContactId
            LEFT JOIN dbo.Address ON dbo.Customer.ContactId  = dbo.Address.ContactId
            WHERE 
                Contact.FirstNameCareOf LIKE @search
                OR Contact.Name LIKE @search
                OR Email.Address LIKE @search
                OR Phone.Number LIKE @search
                OR Address.StreetAddress LIKE @search
                OR Address.City LIKE @search
                OR Address.ZipCode LIKE @search

          union

          --Secondary Contacts
          SELECT Customer.ContactId
          FROM dbo.Customer
          INNER JOIN dbo.Relationship ON dbo.Contact.Id = dbo.Relationship.TargetContactId
          INNER JOIN dbo.Contact on dbo.Contact.id = dbo.Relationship.SourceContactId
          LEFT JOIN dbo.Email ON dbo.Contact.Id = dbo.Email.ContactId
          LEFT JOIN dbo.Phone ON dbo.Contact.Id = dbo.Phone.ContactId
          WHERE 
            Contact.FirstNameCareOf LIKE @search
            OR Contact.Name LIKE @search
            OR Email.Address LIKE @search
            OR Phone.Number LIKE @search)
order by
    Customer.Number
到目前为止,我得到的是:

from customerTable in Customers

    join contactTable in Contacts
        on customerTable.ContactId equals contactTable.Id

    join addressTable in Addresses
        on customerTable.ContactId equals addressTable.ContactId

    // the following may no exists for the customer so we dont want to join them since the customer will not be in the request results because of this  
    //  join phoneTable in Phones
    //      on customerTable.ContactId equals phoneTable.ContactId 
    //      
    //  join emailTable in Emails
    //      on customerTable.ContactId equals emailTable.ContactId

    // alternate method to query email and phone table without effecting the results    
    let emailMatch = Emails.Where (p => p.ContactId == customerTable.ContactId && p.Address.Contains("a"))
    let phoneMatch = Phones.Where (p => p.ContactId == customerTable.ContactId && p.Number.Contains("a"))

    where customerTable.IsActive && ( contactTable.Name.Contains("a") || contactTable.FirstNameCareOf.Contains("a") ||addressTable.StreetAddress.Contains("a") || addressTable.City.Contains("a") ||    
                                          addressTable.ZipCode.Contains("a") || emailMatch.Any()|| phoneMatch.Any() )
 orderby customerTable.Number 
            select new {CustomerNumber = customerTable.Number, contactTable.Name, addressTable.StreetAddress, customerTable.Type.EnumId}
问题

  • 有没有一种简单的方法可以将我的SQL请求转换为linq到实体?一天后,我仍然在对上面的linq请求进行评估

  • 在我的SQL请求中,进行内部连接和左连接的真正和最有效的方法是什么

  • 尝试将确切的SQL请求“语句”转换为linq有意义吗?还是在linq中使用完全不同的方法更好?我的意思是,在SQL中实现这一点的最有效的方法不一定是linq中的相同方法

  • 取消对手机连接的注释时。。。。它不会返回任何没有电话的客户。。。即使该客户的电话桌上没有可加入的内容,也可以返回结果中吗


  • 感谢您的帮助或任何帮助。

    似乎您可以使用正在搜索的4个实体并合并结果

    这是一个相当大的查询,但作为起点,您可以使用它

    var contacts = from c in Contacts
                   where c.FirstNameCareOf.Contains("c") ||
                         c.Name.Contains("c")
                   select c.Customer;
    
    var emails =   from e in Emails
                   where e.Address.Contains("c")
                   select e.Contact.Customer;
    
    然后,当您拥有所有客户时,只需将他们添加到列表中即可

    var customers = new List<Customer>();
    customers.AddRange(contacts);
    customers.AddRange(emails);
    etc..
    
    var客户=新列表();
    客户。添加范围(联系人);
    customers.AddRange(电子邮件);
    等
    
    前三个问题的答案是:使用导航属性。出于某种原因,SQL背景的人在开始编写LINQ时几乎总是使用
    join
    语句。这至少有三个主要缺点:
    join
    语句-

    • 冗长
    • 并没有揭示出关联的多样性。声明

      来自客户中的customerTable
      在联系人中加入contactTable。。。
      
      不告诉我客户联系人是
      1-n
      n-1
      还是
      1-1

    • 容易出错:您必须输入联接列,并且可能会选择错误的列(我看到过这种情况)

    如果使用正确命名的导航属性(如

    来自客户中的客户
    从客户联系人中的cont。。。
    
    简而言之,它表明关联是
    1-n
    ,您只需配置一次关联,就不再关心联接列

    因此,如果您这样做,您的查询的形状将如下

    来自客户中的客户
    客户联系人在哪里
    .Any(cont=>cont.Name.Contains(“a”)
    ||cont.FirstNameCareOf.Contains(“a”)
    ||cont.Address.StreetAddress.Contains(“a”)
    ||续地址城市包含(“a”)
    || ...  )
    ||客户关系
    .Any(rel=>rel.TargetContact.Name.Contains(“a”)
    ||相对TargetContact.FirstNameCareOf.Contains(“a”)
    ||相对TargetContact.Address.StreetAddress.Contains(“a”)
    ||相关TargetContact.Address.City.Contains(“a”)
    || ...  )
    选择客户
    
    (如你所见,我不得不猜测客户关系的多样性)

    这将生成一个SQL查询,其中主谓词由
    EXIST
    语句组成。我认为这比您在中结合使用
    DISTINCT
    要好,因为
    存在
    是一种有效的搜索策略


    至于您的第四个问题:您还可以在查询中包括电话上的匹配项,以及
    |cont.Phone==null

    谢谢您的帮助!我完全错了在林克怎么做。你的回答真的帮助了我。再次感谢