首先查看我的班级结构。
public class CustomerBase
{
public int CustomerID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string Phone { get; set; }
public string Fax { get; set; }
}
public class Customer : CustomerBase
{
public virtual List<Addresses> Addresses { get; set; }
}
public class Addresses
{
[Key]
public int AddressID { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public bool IsDefault { get; set; }
public virtual List<Contacts> Contacts { get; set; }
public int CustomerID { get; set; }
public virtual Customer Customer { get; set; }
}
public class Contacts
{
[Key]
public int ContactID { get; set; }
public string Phone { get; set; }
public string Fax { get; set; }
public bool IsDefault { get; set; }
public int AddressID { get; set; }
public virtual Addresses Customer { get; set; }
}
public class TestDBContext : DbContext
{
public TestDBContext()
: base("name=TestDBContext")
{
}
public DbSet<Customer> Customer { get; set; }
public DbSet<Addresses> Addresses { get; set; }
public DbSet<Contacts> Contacts { get; set; }
}
现在这种方式我试图填充我的客户群,但收到错误。
var bsCustomer1 = (from c in db.Customer
where (c.CustomerID == 2)
select new
{
CustomerID = c.CustomerID,
FirstName = c.FirstName,
LastName = c.LastName,
Addresses = (from ad in c.Addresses
where (ad.IsDefault == true)
from cts in ad.Contacts
where (cts != null && cts.IsDefault == true)
select ad).ToList(),
}).ToList()
.Select(x => new CustomerBase
{
CustomerID = x.CustomerID,
FirstName = x.FirstName,
LastName = x.LastName,
Address1 = x.Addresses.Select(a => a.Address1).SingleOrDefault(),
Address2 = x.Addresses.Select(a => a.Address2).SingleOrDefault(),
Phone = x.Addresses.Select(c => c.Contacts.Select(cd => cd.Phone).SingleOrDefault()),
Fax = x.Addresses.Select(c => c.Contacts.Select(cd => cd.Fax).SingleOrDefault())
}).ToList();
根据我的情况,单个客户可能有多个地址,但我应该有一个默认的地址。单个地址可能有多个联系人详细信息,但应该有一个我要提取的默认地址。
地址1,地址2,电话和传真都在基本客户类中。我想根据 isdefault 从地址和联系人表中提取单个数据,并填充我的客户。我在 linq 方面不是很好。所以无法撰写查询。请帮我写一下。感谢
答案 0 :(得分:1)
请尝试以下代码,猜测它可能符合您的要求。
var bsCustomer1 = db.Customer.Where(p => p.CustomerID == 2)
.Select(x => new CustomerBase
{
CustomerID = x.CustomerID,
FirstName = x.FirstName,
LastName = x.LastName,
Address1 = x.Addresses.First(a => a.IsDefault).Address1,
Address2 = x.Addresses.First(a => a.IsDefault).Address2,
Phone = x.Addresses.First(a => a.IsDefault).Contacts.First(c => c.IsDefault).Phone),
Fax = x.Addresses.First(a => a.IsDefault).Contacts.First(c => c.IsDefault).Fax)
}).ToList();
答案 1 :(得分:1)
当你说:&#34;我想从地址和联系人表中提取单个数据时,根据isdefault是真实的并且填充我的客户&#34;这可能意味着两件事:
关于EF的一些事情:
要创建新对象,您不必引用其上方或下方的对象。您只需要创建它,然后用它来更新数据库。
因此,对于EF的一个例子,我说我有两个数据库表:
我有一个表tePerson,它有字段:PersonId,FirstName,LastName,OrderId。此表具有值
1 Brett X 1
2 Emily X 2
4 Ryan Y 1
10 Mark Z 1
OrderId是表teOrder的外键,只有两个字段:OrderId和Description。
1 Shirt
2 Dress
我从T4生成的POCO对象是:
public partial class tePerson
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public Nullable<int> OrderId { get; set; }
public virtual teOrder teOrder { get; set; }
}
重要的是要注意那个虚拟的teOrder&#39;像我这样指向另一个POCO:
public partial class teOrder
{
public teOrder()
{
this.tePersons = new HashSet<tePerson>();
}
public int OrderId { get; set; }
public string Description { get; set; }
public virtual ICollection<tePerson> tePersons { get; set; }
}
仅从上下文中投影和更新数据库以及更新下面的数据库的示例。要记住的关键是在做“选择”时的对象。在你做一个类似于ToList()&#39;的方法之前,没有实现EF。使它们具体化否则它们是上下文数据集,你无法链接。
public class OtherPerson
{
public int PersonId { get; set; }
public string PersonLongName { get; set; }
public teOrder Order { get; set; }
}
static void Main(string[] args)
{
using (var context = new TesterEntities())
{
//Say I just want to project a new object with a select starting from orders and then traversing up. Not too hard
var newObjects = context.teOrders.Where(order => order.OrderId == 1)
//SelectMan will FLATTEN a list off of a parent or child in a one to many relationship
.SelectMany(peopleInOrderOne => peopleInOrderOne.tePersons)
.ToList()
.Select(existingPerson => new OtherPerson
{
PersonId = existingPerson.PersonId,
PersonLongName = $"{existingPerson.FirstName} {existingPerson.LastName}",
Order = existingPerson.teOrder
})
.ToList();
newObjects.ForEach(newPerson => Console.WriteLine($"{newPerson.PersonId} {newPerson.PersonLongName} {newPerson.Order.Description}"));
// Just an action clause to repeat find items in my context, the important thing to note is that y extends teOrder which is another POCO inside my POCO
Action<string, List<tePerson>> GetOrdersForPeople = (header, people) =>
{
Console.WriteLine(header);
people.ForEach(person => Console.WriteLine($"{person.FirstName} {person.LastName} {person.teOrder.Description}"));
Console.WriteLine();
};
//I want to look at a person and their orders. I don't have to do multiple selects down, lazy loading by default gives me a child object off of EF
GetOrdersForPeople("First Run", context.tePersons.ToList());
//Say I want a new order for a set of persons in my list?
var newOrder = new teOrder { Description = "Shoes" };
context.teOrders.Add(newOrder);
context.SaveChanges();
//Now I want to add the new order
context.tePersons.SingleOrDefault(person => person.PersonId == 1).teOrder = newOrder;
context.SaveChanges();
//I want to rexamine now
GetOrdersForPeople("After changes", context.tePersons.ToList());
//My newOrder is in memory and I can alter it like clay still and the database will know if I change the context
newOrder.Description = "Athletic Shoes";
context.SaveChanges();
GetOrdersForPeople("After changes 2", context.tePersons.ToList());
//Say I want to update a few people with new orders at the same time
var peopleBesidesFirst = context.tePersons.Where(person => person.PersonId != 1).ToList();
var firstPersonInList = context.tePersons.Where(person => person.PersonId == 1).ToList();
var newOrders = new List<teOrder> {
new teOrder { Description = "Hat", tePersons = peopleBesidesFirst },
new teOrder { Description = "Tie", tePersons = firstPersonInList }
};
context.teOrders.AddRange(newOrders);
context.SaveChanges();
GetOrdersForPeople("After changes 3", context.tePersons.ToList());
}
Console.ReadLine();
}