首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将SQL转换为Linq到实体

将SQL转换为Linq到实体
EN

Stack Overflow用户
提问于 2015-09-30 19:22:27
回答 2查看 29关注 0票数 1

SQL请求:

代码语言:javascript
复制
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

到目前为止,这就是我所得到的:

代码语言:javascript
复制
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}

问题

  1. 是否有一种简单的方法可以将我的SQL请求转换为linq?一天后,我仍然在处理上面的linq请求
  2. 在我的SQL请求中,执行内部连接和左连接的真正和最有效的方式是什么?
  3. 尝试将确切的SQL请求“语句”转换为linq是否有意义?还是在linq中用一种完全不同的方法更好呢?我的意思是,在SQL中最具表现力的方法在linq中根本不一定是相同的方法?
  4. 当取消电话连接的评论时.没有电话就不能退货..。是否有可能返回结果,即使没有加入电话表为该客户?

谢谢你的帮助或任何东西。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-09-30 20:33:25

前三个问题的答案是:使用导航属性。出于某种原因,来自SQL背景的人几乎总是从使用join语句编写LINQ开始。这至少有三个主要缺点:join语句-

  • 冗长
  • 并不能揭示出一个组合的多样性。声明 从客户中的customerTable到contactTable的联系人. 不告诉我客户联系是1-nn-1还是1-1
  • 容易出错:您必须输入联接列,并且可能会选择错误的列(我已经看到这种情况)。

如果使用正确命名的导航属性,所有这些都会更改,如

代码语言:javascript
复制
from cust in Customers
from cont in cust.Contacts ...

很短,它显示关联是1-n,并且您只配置了一次关联,并且不再关心连接列。

因此,如果您这样做,您的查询将被构造为

代码语言:javascript
复制
from cust in Customers
where cust.Contacts
          .Any(cont => cont.Name.Contains("a")
                    || cont.FirstNameCareOf.Contains("a")
                    || cont.Address.StreetAddress.Contains("a")
                    || cont.Address.City.Contains("a")
                    || ...  )
   || cust.Relationships
          .Any(rel => rel.TargetContact.Name.Contains("a")
                   || rel.TargetContact.FirstNameCareOf.Contains("a")
                   || rel.TargetContact.Address.StreetAddress.Contains("a")
                   || rel.TargetContact.Address.City.Contains("a")
                   || ...  )
select cust

(正如你所看到的,我不得不猜测客户关系的多样性)

这将生成一个SQL查询,其中主要谓词由EXIST语句组成。我认为这比INDISTINCT的组合要好,因为EXIST是一种高效的搜索策略。

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

票数 1
EN

Stack Overflow用户

发布于 2015-09-30 19:48:28

似乎你可以用你正在搜索的4个实体来组合结果。

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

代码语言:javascript
复制
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;

然后,当你有了所有的客户,只需将他们添加到一个列表。

代码语言:javascript
复制
var customers = new List<Customer>();
customers.AddRange(contacts);
customers.AddRange(emails);
etc..
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32874062

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档