所以我对LINQ很新,遇到了一个我无法找到解决方案的问题。
当我看到有关Group Joins的文章时,我正在阅读msdn上的LINQ指南。
https://docs.microsoft.com/en-us/dotnet/csharp/linq/perform-grouped-joins
我通读了这个页面并认为这正是我完成查询所需要的。对于我的查询,我正在调用表A,其中包含我用来与联系人表联接的ID。然后,来自联系人表的ID用于在相同的ID上与表C连接。表C包含一个子ID,然后用于与联系人表联接以检索联系人列表。联系人主ID用于与电话号码表连接。联系人可以有多个电话号码。
var query = (from a in db.TableA
join b in db.Contacts on a.PrimaryID equals b.PrimaryID
join c in db.tableC on b.PrimaryID equals c.ParentPrimaryID
join d in db.Contacts on c.ChildID equals d.PrimaryID
join e in db.TablePhoneNbrs on d.PrimaryID equals e.PrimaryID into gj
where a.PrimaryID == id
select new
{
PrimaryId = d.PrimaryId,
FirstName = d.FirstName,
LastName = d.LastName,
phhoneNbrs = gj
});
从文章开始,我读到如果你加入两个表然后在连接后调用“into”,它会将查询结果存储到你指定为集合的任何变量中。因此,在上面的查询中,我尝试使用单个/多个电话号码加入各个联系人,然后调用“into”返回一个集合,而不是复制每个号码的联系人,但它失败了。它不是为多个号码的联系人返回电话号码集合,而是复制了返回的每个号码的联系人。
然后,我尝试减少查询,而是使用特定的联系人ID号,并使用一个结果进行测试。
var query2 = (from a in db.Contacts
join b in db.TablePhoneNbrs on a.PrimaryID equalsb.PrimaryID into gj
where a.PrimaryID == 1234
select new
{
PrimaryID = a.PrimaryID,
FirstName = a.FirstName,
LastName = a.LastName,
phhoneNbrs = gj
}).ToList();
这很有效!因此,当我使用单个联系人ID执行查询时,它正确地将联系人及其两个电话号码作为附加到一个联系人对象的阵列返回。
我的问题是,如果我第一个导致其失败的查询出错了吗?
更新:有一个更好的例子! 所以这几乎就是关系如何与表一起工作。但是,这个例子似乎有效。 Query2是在工作中失败的那个。当它返回一个联系人时,它不是将该号码存储在一个集合中并将其分配给Number变量,而是复制它所拥有的每个号码的联系人。
class Contact
{
public int primaryID { get; set; }
public string name { get; set; }
}
class TableC
{
public int parentID { get; set; }
public int childID { get; set; }
}
class TablePhoneNbr
{
public int primaryID { get; set; }
public string phoneNbr { get; set; }
}
class TableEmail
{
public int primaryID { get; set; }
public string email { get; set; }
}
class Program
{
static void Main(string[] args)
{
Contact mainContact = new Contact { primaryID = 1, name = "My Test Code" };
Contact Jim = new Contact { primaryID = 2, name = "Jim" };
Contact Bob = new Contact { primaryID = 3, name = "Bob" };
Contact Ashley = new Contact { primaryID = 4, name = "Ashley" };
Contact Mary = new Contact { primaryID = 5, name = "Mary" };
TableC child1 = new TableC { parentID = 1, childID = 2 };
TableC child2 = new TableC { parentID = 1, childID = 3 };
TableC child3 = new TableC { parentID = 1, childID = 4 };
TableC child4 = new TableC { parentID = 1, childID = 5 };
TablePhoneNbr Nbr1 = new TablePhoneNbr { primaryID = 2, phoneNbr = "123456" };
TablePhoneNbr Nbr2 = new TablePhoneNbr { primaryID = 2, phoneNbr = "999999" };
TablePhoneNbr Nbr3 = new TablePhoneNbr { primaryID = 3, phoneNbr = "888888" };
TablePhoneNbr Nbr4 = new TablePhoneNbr { primaryID = 4, phoneNbr = "777777" };
TableEmail Email1 = new TableEmail { primaryID = 2, email = "Hello World" };
TableEmail Email2 = new TableEmail { primaryID = 3, email = "Goodbye World" };
TableEmail Email3 = new TableEmail { primaryID = 4, email = "Testing1" };
TableEmail Email4 = new TableEmail { primaryID = 5, email = "Testing2" };
// Create two lists.
List<Contact> contacts = new List<Contact> { mainContact, Jim, Bob, Ashley, Mary };
List<TableC> relations = new List<TableC> { child1, child2, child3, child4 };
List<TablePhoneNbr> numbers = new List<TablePhoneNbr> { Nbr1, Nbr2, Nbr3, Nbr4 };
List<TableEmail> emails = new List<TableEmail> { Email1, Email2, Email3, Email4 };
// Create a list where each element is an anonymous type
// that contains the person's first name and a collection of
// pets that are owned by them.
var query = from primary in contacts
join relation in relations on primary.primaryID equals relation.parentID
join person in contacts on relation.childID equals person.primaryID
join number in numbers on person.primaryID equals number.primaryID into gj
select new { FirstName = person.name, Number = gj };
foreach (var v in query)
{
// Output the owner's name.
Console.WriteLine("{0}:", v.FirstName);
// Output each of the owner's pet's names.
foreach (TablePhoneNbr number in v.Number)
Console.WriteLine(" {0}", number.phoneNbr);
}
var query2 = from primary in contacts
join relation in relations on primary.primaryID equals relation.parentID
join person in contacts on relation.childID equals person.primaryID
join email in emails on person.primaryID equals email.primaryID
join number in numbers on person.primaryID equals number.primaryID into gj
select new { FirstName = person.name, Number = gj, Email = email.email };
foreach (var v in query2)
{
// Output the owner's name.
Console.WriteLine("{0}:", v.FirstName);
Console.WriteLine("{0}:", v.Email);
// Output each of the owner's pet's names.
foreach (TablePhoneNbr number in v.Number)
Console.WriteLine(" {0}", number.phoneNbr);
}
Console.ReadLine();
}
}
答案 0 :(得分:0)
尝试拔出联系人并使用Distinct()
,然后再尝试获取他们的号码:
var contacts = (from a in db.TableA
where a.PrimaryID == id
join b in db.Contacts on a.PrimaryID equals b.PrimaryID
join c in db.tableC on b.PrimaryID equals c.ParentPrimaryID
join d in db.Contacts on c.ChildID equals d.PrimaryID
select new { d.PrimaryID, d.FirstName, d.LastName } ).Distinct();
var query = (from d in contacts
join e in db.TablePhoneNbrs on d.PrimaryID equals e.PrimaryID into ej
select new {
PrimaryId = d.PrimaryID,
FirstName = d.FirstName,
LastName = d.LastName,
phhoneNbrs = ej
});
注意,对Distinct
运行PrimaryID
然后查找FirstName
和LastName
可能会更好,但这应该在SQL端运行,所以我不认为这很重要。