示例:
我正在输入新发票。对于此发票,我需要输入客户。让我们假设我们检索了一个客户列表:
var list = Context.Set<Customer>().ToList();
我在这里看到两个问题:
1)我不需要为客户提供所有信息,我只需要ID,代码和名称
2)当前DbContext中的客户是只读的,因此如果可以告诉DbContext不监控其状态,以提高性能,那就太好了。
问题:
1)我们可以只为客户加载部分数据,但仍然可以将其分配给发票(参见下面的代码)?
2)我们可以告诉DbContext不要监视客户的变化,并且仍然可以这样做:
Invoice.Customer = CustomerList[10];
答案 0 :(得分:2)
没有直接的方法可以完全你想要的东西,但是你可以通过一些妥协来实现你的目标。
我不需要为客户提供所有信息,我只需要ID, 代码和名称
EF无法创建部分加载的实体,但您可以创建匿名类型:
Context.Customers.Select(c => new {Id = c.CustomerId, Code = c.Code, Name = c.Name}).Tolist()
如果你可以使用新的匿名类型然后使用它,或者你可以遍历该列表,创建实际的客户对象。
当前DbContext中的客户是只读的,所以如果它是好的 有可能告诉DbContext不要监视他们的状态,改进 性能
EF提供AsNoTracking()的扩展名,它将完全符合您的要求:
var list = Context.Set<Customer>().AsNoTracking().ToList();
根据您从上面选择的内容,以下代码可能会更改,但此代码确实可以实现您的目标。部分加载客户,但仍允许您将客户附加到发票。
注意:您需要先将客户附加到您的上下文,然后才能使用它,然后将其设置为Unchanged状态将阻止它覆盖现有数据。
m = new Model();
var list = m.Customers.Select(c => new {Id = c.CustomerId, Code = c.Code, Name = c.Name});
List<Customer> customerList = new List<Customer>();
foreach (var item in list)
{
customerList.Add(new Customer()
{
CustomerId = item.Id,
Code = item.Code,
Name = item.Name
});
}
Invoice i = new Invoice();
var customer = customerList.First();
m.Customers.Attach(customer);
m.Entry(customer).State = EntityState.Unchanged;
i.Customer = customer;
m.Invoices.Add(i);
m.SaveChanges();