我想通过linq join填充我的子列表。怎么做到这一点?下面列出了我无法弄清楚的代码。
var model = (from personel in db.Personels
where personel.ID == id
from contact in personel.ContactTypes
join contactType in db.ContactTypes on contact.ContactTypeId equals contactType.ID
select new PersonelWithContactListDto
{
PersonelName = personel.PersonelName,
PersonelLastname = personel.PersonelLastname,
PersonelPrivateNo = personel.PersonelPrivateNo,
// here how to select my sublist. If I leverage
// let = dbobjects.DefaultIfEmpty() then I am no
// longer able to specify contactType from another table.
//Contact = contacts.Select(x => new ContactListDto
//{
// Value = x.Value,
// ContactType = contactType.Value,
// ID = x.ID
//}).ToList()
}).FirstOrDefault();
这是我的dto课程。
public class PersonelWithContactListDto
{
public string PersonelName { get; set; }
public string PersonelLastname { get; set; }
public int PersonelPrivateNo { get; set; }
public IList<ContactListDto> Contacts { get; set; }
}
以下是我的关键地图的域类。
它的人员类
public class Personel
{
public int ID { get; set; }
[Required]
public string PersonelName { get; set; }
[Required]
public string PersonelSurname { get; set; }
[Required]
[Index(IsUnique = true)]
public int PersonelPrivateNo { get; set; }
public virtual ICollection<Contact> Contacts { get; set; }
}
每个人可能有多个的联系课
public class Contact
{
public int ID { get; set; }
public int ContactTypeId { get; set; }
[ForeignKey("ContactTypeId")]
public virtual ContactType ContactType { get; set; }
[Required]
public string Value { get; set; }
[ForeignKey("PersonelId")]
public virtual Personel Personel { get; set; }
public int PersonelId { get; set; }
}
以下是每个联系人的类型信息。
public class ContactType
{
public int ID { get; set; }
[Required]
public string Value { get; set; }
}
有人能让我朝着正确的方向前进吗?
答案 0 :(得分:1)
您正在错误的地方进行加入。试试这个:
var model = (from person in personel
where person.ID == id
select new PersonelWithContactListDto {
PersonelName = person.PersonelName,
PersonelLastname = person.PersonelSurname,
PersonelPrivateNo = person.PersonelPrivateNo,
Contacts = (from contact
in person.Contacts
join contactType in contactTypes
on contact.ContactTypeId equals contactType.ID
select new ContactListDto {
Value = contact.Value,
ContactType = contactType.Value,
ID = contact.ID
}).ToList()
}).FirstOrDefault();
答案 1 :(得分:0)
显然你有一个id
,而且你希望这个Personel
只有id
以及他所有Contacts
。您不希望Personel
的所有属性都包含此id
,但只有PersonelName
,PersonelLastname
和PersonelPrivateNo
。
从提取的Contact
的每个Personel
中,您也不想要所有属性,但只有Value
,ContactType
和id
< / p>
您的Personel
类已经拥有一个包含您想要的Contacts
的属性。那么为什么要加入呢?使用ICollection和你的框架(看起来像实体框架)将知道需要连接:
var personWithHisContacts = myDbContext.Personels
.Where(person => person.Id == id)
.Select(person => new
{
// select only the Person properties you plan to use:
Name = person.PersonelName,
LastName = person.PersonelLastName,
PrivateNo = person.PersonelPrivateNo,
// I want all contacts of this Person:
Contacts = person.Contacts
.Select(contact => new
{
// again: select only the properties you plan to use:
Id = contact.Id,
Value = contact.Value,
ContactTypeValue = contact.ContactType.Value,
})
.ToList(),
});
我认为使用ICollection
的{{1}}是一种巧妙的方式,可以清楚地表明每个Contacts
都有零个或多个Personel
。它还隐藏在内部,这是使用两个带有外键的单独表来完成的。
您是否注意到Contacts
部分占用了大部分查询?
您的框架将知道使用ICollection需要加入。如果您真的认为明确指定连接,请执行以下操作:
Select
var personWithHisContacts = myDbContext.Personels // from all Persons
.Where(person => person.Id == id) // take the one with id
.GroupJoin(myDbContext.Contacts // GroupJoin with all Contacts
person => person.Id, // from each person take Id
contact => contact.PersonelId, // from each contact take PersonelId
(person, contacts) => new // when they match, make a new object
{ // containing only the properties you plan to use
Name = person.PersonelName,
LastName = person.PersonelLastName,
PrivateNo = person.PersonelPrivateNo,
// I want all contacts of this Person:
Contacts = contacts.Select(contact => new
{
// again: select only the properties you plan to use:
Id = contact.Id,
Value = contact.Value,
ContactTypeValue = contact.ContactType.Value,
})
.ToList(),
});
部分并没有真正改变。 GroupJoin改变了ICollection的使用。我不明白为什么有人会更喜欢ICollection方法之上,但你真的想要......
答案 2 :(得分:-1)
看看这是否有帮助:
class Program
{
static void Main(string[] args)
{
DB db = new DB();
int id = 123;
var model = (from personel in db.Personels
where personel.ID == id
from contact in db.ContactTypes
join contactType in db.ContactTypes on contact.ID equals contactType.ID
select new PersonelWithContactListDto
{
PersonelName = personel.PersonelName,
PersonelLastname = personel.PersonelSurname,
PersonelPrivateNo = personel.PersonelPrivateNo,
// here how to select my sublist. If I leverage
// let = dbobjects.DefaultIfEmpty() then I am no
// longer able to specify contactType from another table.
Contacts = personel.Contacts.Select(x => new Contact() {
Value = x.Value,
ID = x.ID
}).ToList()
}).ToList();
}
}
public class DB
{
public List<Personel> Personels { get; set; }
public List<ContactType> ContactTypes { get; set; }
}
public class PersonelWithContactListDto
{
public string PersonelName { get; set; }
public string PersonelLastname { get; set; }
public int PersonelPrivateNo { get; set; }
public List<Contact> Contacts { get; set; }
}
public class Personel
{
public int ID { get; set; }
//[Required]
public string PersonelName { get; set; }
//[Required]
public string PersonelSurname { get; set; }
//[Required]
//[Index(IsUnique = true)]
public int PersonelPrivateNo { get; set; }
public virtual ICollection<Contact> Contacts { get; set; }
}
public class Contact
{
public int ID { get; set; }
public int ContactTypeId { get; set; }
//[ForeignKey("ContactTypeId")]
public ContactType ContactType { get; set; }
//[Required]
public string Value { get; set; }
//[ForeignKey("PersonelId")]
public virtual Personel Personel { get; set; }
public int PersonelId { get; set; }
}
public class ContactType
{
public int ID { get; set; }
//[Required]
public string Value { get; set; }
}