【问题标题】:Changes are not tracked when using projections in Entity Framework Core 3.1在 Entity Framework Core 3.1 中使用投影时不跟踪更改
【发布时间】:2020-01-30 20:55:19
【问题描述】:

有预测(0 次更改):

var changesBefore = Db.ChangeTracker.Entries<OrderLocationEntity>().ToList(); //before change - 0

var orderLocation = Db.OrderLocation.AsTracking().Select(ol => new OrderLocationEntity
{
    Id = ol.Id,
    Address = ol.Address,
    City = ol.City,
    Created = ol.Created,
    OrderId = ol.OrderId,
    Zip = ol.Zip
}).First();

orderLocation.Address = "address";

var changesAfter = Db.ChangeTracker.Entries<OrderLocationEntity>().ToList(); //after change - 0

无预测(1 处更改)

var changesBefore = Db.ChangeTracker.Entries<OrderLocationEntity>().ToList(); //before change - 0

var orderLocation = Db.OrderLocation.AsTracking().First();

orderLocation.Address = "address";

var changesAfter = Db.ChangeTracker.Entries<OrderLocationEntity>().ToList(); //after change - 1

设置

Microsoft.EntityFrameworkCore 3.1.1

Microsoft.EntityFrameworkCore.Sqlite 3.1.1

var options = new DbContextOptionsBuilder<OrderDatabaseContext>()
                .UseSqlite("DataSource=:memory:")
                .Options;

如果结果集包含来自 LINQ 组合的实体类型,EF Core 将跟踪它们。

来源

https://docs.microsoft.com/en-us/ef/core/querying/tracking

为什么使用投影时没有跟踪更改?

【问题讨论】:

  • “为什么在使用投影时不跟踪更改?”因为 EF Core 设计人员采用了这种方式。为什么要投影到相同的实体类型?跳过检索某些属性?嗯,很可能这就是他们没有被跟踪的原因。

标签: c# .net-core entity-framework-core entity-framework-core-3.1


【解决方案1】:

注意“实体类型”:

如果结果集包含来自 LINQ 的 实体类型 组合,EF Core 将跟踪它们。

来自相同的文档:

如果结果集不包含任何实体类型,则不跟踪 完成了。

您的投影不包含实体类型,因此不会跟踪更改。

例如,如果您将引入属性来保留OrderLocationEntity 实例,则该实例将被上下文跟踪

var location = Db.OrderLocation.AsTracking()
    .Select(ol => new OrderLocationEntity
    {
        Id = ol.Id,
        Address = ol.Address,
        City = ol.City,
        Created = ol.Created,
        OrderId = ol.OrderId,
        Zip = ol.Zip,
        Location = ol // entity instance passed to the projected object
    })
    .First();

location.Location.Address = "New Address"; 

Db.ChangeTracker.Entries<OrderLocationEntity>().ToList(); //after change - 1

【讨论】:

  • 我不...明白。为什么他们会启用跟踪子属性而不是“基础”对象,在这种情况下是“新的 OrderLocationEntity”?因为 OrderLocationEntity 是 Db.OrderLocation。
  • 因为new OrderLocationEntity 是一个新实例,并不是由实际的“查询”创建的
【解决方案2】:

因为他们不跟踪他们。这在 3.1 中被禁用,项目自动添加 AsNoTracking。

许多无法真正解释并使 EfCore 3.1 成为无法与 Ef 6.4 竞争的产品的决策中的一个。

【讨论】:

  • 那么“AsTracking”不应该覆盖该默认设置吗?
  • 几乎没有?没有把握。关键是,由于没有针对它们的更新机制,因此没有跟踪投影实体的更改。投影仅在一个方向上起作用。
  • 但是 EF6 根本不允许投影到实体类型,不是吗?所以 EF Core 在这方面实际上更好。而且投影的实体从未被跟踪过,所以这也不是新行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-25
  • 2017-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多