0

例子:

我正在输入新发票。对于这张发票,我需要输入一个客户。假设我们检索了一个客户列表:

var list = Context.Set<Customer>().ToList();

在这里,我看到两个问题:

1) 我不需要为客户带来所有信息,我只需要 Id, Code 和 Name

2)当前 DbContext 中的客户是只读的,所以如果可以告诉 DbContext 不要监视他们的状态以提高性能,那就太好了。

问题:

1)我们可以只为客户加载部分数据,但仍然可以将其分配给发票(见下面的代码)?

2)我们可以告诉 DbContext 不要监视客户的更改,并且仍然可以这样做:

Invoice.Customer = CustomerList[10];
4

1 回答 1

2

没有直接的方法可以完全按照您的意愿行事,但您可以通过一些妥协来实现您的目标。

我不需要为客户带来所有信息,我只需要 Id, Code 和 Name

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();
于 2012-09-21T14:41:05.827 回答