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请求中执行内连接和左连接的真实且最高效的方法是什么?
尝试转换EXACT SQL请求"语句"是否有意义到linq?或者在linq中使用完全不同的方法更好吗?我的意思是在SQL中执行此操作的最高效方法在linq中根本不一定是相同的方法吗?
当取消注释连接到手机....它不会返回没有手机的任何客户...是否可以返回结果,即使手机桌上没有任何东西可以加入客户?
感谢您提供任何帮助或任何事情。
答案 0 :(得分:1)
您的前三个问题的回答是:使用导航属性。出于某种原因,来自SQL背景的人几乎总是开始用join
语句编写LINQ。这至少有三个主要缺点:join
语句 -
没有揭示关联的多样性。声明
from customerTable in Customers
join contactTable in Contacts ...
未告诉我,客户联系人是1-n
,n-1
还是1-1
。
容易出错:你必须输入连接列,你可以选错了(我已经看过它了。)
如果您使用正确命名的导航属性,例如
,这一切都会发生变化from cust in Customers
from cont in cust.Contacts ...
它很短,它表明关联是1-n
,您只需配置一次关联,而不再关心连接列。
因此,如果您这样做,您的查询将形如
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
语句组成。我认为这比IN
和DISTINCT
的组合更好,因为EXIST
是一种有效的搜索策略。
关于您的第四个问题:您还可以在查询中包含电话中的匹配项以及|| cont.Phone == null
。
答案 1 :(得分:0)
好像你可以使用你正在搜索的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..