简体   繁体   English

EF Core 查询不反映更新的属性而不保存

[英]EF Core query not reflecting updated property without saving

With this code snippet, I query for an entity in my SQL database, and then update a property on that entity.使用此代码片段,我在 SQL 数据库中查询实体,然后更新该实体的属性。

This query should filter out that entity because I just modified it, but the first one does not.这个查询应该过滤掉那个实体,因为我刚刚修改了它,但第一个没有。 For some reason, the second query does return what I expect.出于某种原因,第二个查询确实返回了我所期望的。

In my scenario, the ProductionOrderStep entity is a one-to-many relationship to the ProductionOrder entity.在我的场景中, ProductionOrderStep ProductionOrder是一对多的关系。

I do not want to add a call to SaveChanges .我不想添加对SaveChanges的调用。

Is this a bug in EF Core?这是 EF Core 中的错误吗? Or is this intended behaviour?或者这是预期的行为?

[HttpGet("test")]
public void Test()
{
    var productionOrderStepId = 356664;
    var productionOrderId = 305712;

    var pos = context.ProductionOrderStep
                     .Where(x => x.ProductionOrderStepId == productionOrderStepId)
                     .FirstOrDefault();
    pos.Status = 2; // Changes status from 1 to 2

    var incorrectResult = context.ProductionOrder
                                 .Where(x => x.ProductionOrderId == productionOrderId)
                                 .SelectMany(x => x.ProductionOrderSteps)
                                 .Where(pos => pos.Status < 2)
                                 .ToList();

    var correctResult = context.ProductionOrder
                               .Where(x => x.ProductionOrderId == productionOrderId)
                               .SelectMany(x => x.ProductionOrderSteps)
                               .ToList()
                               .Where(pos => pos.Status < 2)
                               .ToList();
}

public class MyContext : DbContext
{
    public MyContext(DbContextOptions<MyContext> options): base(options)
    {}

    public virtual DbSet<ProductionOrder> ProductionOrder { get; set; }
    public virtual DbSet<ProductionOrderStep> ProductionOrderStep { get; set; }
}

public class ProductionOrderStep
{
    public int ProductionOrderStepId { get; set; }
    public int ProductionOrderId { get; set; }
    public int Status { get; set; }

    public virtual ProductionOrder ProductionOrder { get; set; }
}

public class ProductionOrderStepConfiguration : IEntityTypeConfiguration<ProductionOrderStep>
{
    public void Configure(EntityTypeBuilder<ProductionOrderStep> builder)
    {
        builder.HasOne(d => d.ProductionOrder)
               .WithMany(p => p.ProductionOrderSteps)
               .HasForeignKey(d => d.ProductionOrderId);
    }
}

public class ProductionOrder
{
    public int ProductionOrderId { get; set; }

    public virtual ICollection<ProductionOrderStep> ProductionOrderSteps { get; set; }
}

It is intended behaviour.这是预期的行为。 A basic breakdown of the behaviour you are seeing:您所看到的行为的基本细分:

var incorrectResult = context.ProductionOrder  
    .Where(x => x.ProductionOrderId == productionOrderId)
    .SelectMany(x => x.ProductionOrderSteps)
    .Where(pos => pos.Status < 2)
    .ToList();

This builds an SQL query that will attempt to load any ProductionOrderSteps for a given ProductionOrder where their Status < 2. That WHERE execution step goes to SQL.这将构建一个 SQL 查询,该查询将尝试为给定的 ProductionOrder 加载任何其 Status < 2 的 ProductionOrderSteps。该 WHERE 执行步骤转到 SQL。 Since you have updated an entity and not committed the change to the database, that query will not know about your change so EF will not return your expected row.由于您已更新实体并且未将更改提交到数据库,因此该查询将知道您的更改,因此 EF 不会返回您预期的行。

var correctResult = context.ProductionOrder
    .Where(x => x.ProductionOrderId == productionOrderId)
    .SelectMany(x => x.ProductionOrderSteps)
    .ToList()
    .Where(pos => pos.Status < 2)
    .ToList();

In this case, you are telling EF to run a query to load all Production Order Steps for a given Production Order.在这种情况下,您告诉 EF 运行查询以加载给定生产订单的所有生产订单步骤。 Since your updated entity is already tracked, EF will return that updated reference along with the other Production Order Steps that it might load from the DB.由于您的更新实体已被跟踪,EF 将返回该更新的参考以及它可能从数据库加载的其他生产订单步骤。 THe Where condition is done in-memory so the Status will reflect your updated change. Where条件在内存中完成,因此状态将反映您更新的更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM