C# 如何使用EF填充我的基础客户
先看我的班级结构C# 如何使用EF填充我的基础客户,c#,entity-framework,linq,C#,Entity Framework,Linq,先看我的班级结构 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; } pu
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; }
}
根据我的情况,单个客户可能有多个地址,但应该有一个默认地址,我正在提取。一个地址可能有多个联系人的详细信息,但应该有一个默认的我拉
address1、address2、电话和传真属于基本客户类别。我想根据isdefault从地址和联系人表中提取单个数据,并填充我的客户。我的linq不太好。因此无法组合查询。请帮我作曲。谢谢请尝试下面的代码,我想它可能适合您的要求
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();
尝试下面的代码,猜测它可能适合您的请求
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();
当您说:“我想根据isdefault从address和contacts表中提取单个数据并填充我的客户”时,不知道您的实际意思,这可能意味着两件事:
1 Brett X 1
2 Emily X 2
4 Ryan Y 1
10 Mark Z 1
OrderId是表的外键,该表只有两个字段: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; }
}
公共部分类
{
公共int PersonId{get;set;}
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共可为空的OrderId{get;set;}
公共虚拟teOrder teOrder{get;set;}
}
需要注意的是,“虚拟teOrder”指向我的另一个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; }
}
公共偏序类
{
公共秩序()
{
this.tePersons=newhashset();
}
公共int-OrderId{get;set;}
公共字符串说明{get;set;}
公共虚拟ICollection tePersons{get;set;}
}
示例,用于从上下文中投影和更新数据库,以及更新下面的数据库。要记住的关键一点是,在使用EF进行“选择”时,只有使用“ToList()”这样的方法使对象具体化,对象才能实现。否则,它们是无法链接的上下文数据库集
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();
}
公共类其他人
{
公共int PersonId{get;set;}
公共字符串PersonLongName{get;set;}
公共秩序{get;set;}
}
静态void Main(字符串[]参数)
{
使用(var context=newtesterentities())
{
//假设我只想用一个select从orders开始,然后向上遍历来投影一个新对象。不太难
var newObjects=context.teOrders.Where(order=>order.OrderId==1)
//SelectMan会将一对多关系中的父项或子项列表展平
.SelectMany(peopleInOrderOne=>peopleInOrderOne.tePersons)
托利斯先生()
.选择(existingPerson=>new OtherPerson
{
PersonId=现有Person.PersonId,
PersonLongName=$“{existingPerson.FirstName}{existingPerson.LastName}”,
订单=existingPerson.teOrder
})
.ToList();
newObjects.ForEach(newPerson=>Console.WriteLine($“{newPerson.PersonId}{newPerson.PersonLongName}{newPerson.Order.Description}”);
//只是一个在我的上下文中重复find items的action子句,需要注意的是y扩展了teOrder,这是我的POCO中的另一个POCO
Action GetOrdersForPeople=(标题,人物)=>
{
控制台写入线(标题);
people.ForEach(person=>Console.WriteLine($“{person.FirstName}{person.LastName}{person.teOrder.Description}”);
Console.WriteLine();
};
//我想看看一个人和他们的订单。我不需要做多次向下选择,默认情况下,延迟加载会给我一个子对象
GetOrdersForPeople(“第一次运行”,context.tePersons.ToList());
//假设我想为我名单上的一组人下一个新订单?
var newOrder=new teOrder{Description=“Shoes”};
context.teOrders.Add(newOrder);
SaveChanges();
//现在我想添加新订单
context.tePersons.SingleOrDefault(person=>person.PersonId==1).teOrder=newOrder;
SaveChanges();
//我想现在就去
GetOrdersForPeople(“更改后”,context.tePersons.ToList());
//我的新订单在内存中,我可以像粘土一样修改它,如果我更改了上下文,数据库就会知道
newOrder.Description=“运动鞋”;
SaveChanges();
GetOrdersForPeople(“更改后2”,context.tePersons.ToList());
//假设我想同时用新订单更新几个人
var peopleBesidesFirst=context.tePersons.Where(person=>person.PersonId!=1.ToList();
var firstPersonInList=context.tePersons.Where(person=>person.PersonId==1.ToList();
var newOrders=新列表{
新的teOrder{Description=“Hat”,tePersons=peopleBesidesFirst},
新命令{Description=“Tie”,tePersons=firstPersonInList}
};
context.teOrders.AddRange(newOrders);
SaveChanges();
GetOrdersForPeople(“更改后3”,context.tePersons.ToList());
}
Console.ReadLine();
}
当您说:“我想根据isdefault从地址和联系人表中提取单个数据并填充我的客户”时,您并不知道您的实际意思