我遇到了问题,如果有人能提供帮助,我将不胜感激。我有3个db表中的3个列表。帐户,联系方式和联系方式。问题是当我尝试向我的查询中添加2个额外字段时,它会复制记录,例如结果应该在列表中包含700行,但如果我添加contact.firstname和contact.lastname,则结果为8000.
每个帐户可以有多个联系人, 每个联系人都有许多联系方式
var Dataset = (from account in ctx.Accounts
from contact in ctx.Contacts
from contactdetails in ctx.ContactDetails.Where(x => x.id == account.id || x.id ==
account.contactdetailsid)
select new { account.id, account.Reference, account.AccountName, contactdetails.Title,
account.Balance }).Distinct().ToList();
我似乎无法弄清楚为什么在我改为以下时添加contact.firstname和contact.lastname会导致重复记录:结果从700到8000。
select new { account.id, account.Reference, account.AccountName, contactdetails.Title,
account.Balance, contact.firstname , contact.lastname }).Distinct().ToList();
这不会给出正确的结果
答案 0 :(得分:6)
您正在与帐户,联系人和联系人详细信息进行外部联接。因此,对于每个帐户,对于每个联系人,对于符合您条件的每个ContactDetail,您最终都会在结果集中输入一个条目。有人试图通过在结果集上抛出一个.Distinct()
来解决这个问题,这恰好可以过滤掉结果。但是只要从contact
添加属性,最终会为查询之前返回的每个对象提供一堆不同的名字和姓氏。
你可能想做这样的事情:
var Dataset = (from account in ctx.Accounts
from contact in account.Contacts
from contactdetails in contact.ContactDetails
select new { account.id, account.Reference, account.AccountName, contactdetails.Title,
account.Balance, contact.firstname , contact.lastname })
.ToList();
如果您没有导航属性,则可以使用join
或where
子句获得相同的结果:
var Dataset = (from account in ctx.Accounts
join contact in ctx.Contacts
on account.id equals contact.accountid
join contactdetails in ctx.ContactDetails
on contact.contactdetailsid equals contactdetails.id
select new { account.id, account.Reference, account.AccountName, contactdetails.Title,
account.Balance, contact.firstname , contact.lastname })
.ToList();
......或......
var Dataset = (from account in ctx.Accounts
from contact in ctx.Contacts
where account.id == contact.accountid
from contactdetails in ctx.ContactDetails
where contact.contactdetailsid == contactdetails.id
select new { account.id, account.Reference, account.AccountName, contactdetails.Title,
account.Balance, contact.firstname , contact.lastname })
.ToList();
这些方法中的任何一个都应该生成完全相同的执行计划,但join
子句从语义角度更好地表示您的意图。
答案 1 :(得分:0)
来自StriplingWarrior帖子,它帮助我找到了一个有效的解决方案。
var Dataset = (
from account in ctx.Accounts
from contact in ctx.Contacts.Where(x => x.accountid == account.id)
from contactdetails in ctx.ContactDetails.Where(x => x.id == contact.contactdetailsid)
select new {
AccountID = account.id,
Reference = account.Reference,
AccountName = account.AccountName,
External = contact == null ? String.Empty : (contact.External),
Phone = contactdetails == null ? String.Empty : (contactdetails.Title),
Balance = account.Balance,
ContactName = contact == null ? String.Empty : (contact.firstname + " " + contact.lastname),
}).ToList();