gpt4 book ai didi

c# - DbContext 不返回本地对象

转载 作者:行者123 更新时间:2023-11-30 20:29:23 24 4
gpt4 key购买 nike

我正在使用工作单元模式,该模式在对 webapi 请求执行完所有操作后调用 dbcontext.SaveChanges。在部分请求中,我向 dbcontext 添加了一个新客户。

dbContext.Customers.Add(new Customer());

稍后在请求中(通常在域事件处理程序中),我使用相同的 dbcontext 将客户拉回。

_dbContext.Customers.FirstOrDefault(x => x.Id == id);


public abstract class Customer
{
public Customer()
{
Id = Guid.NewGuid();
}

}

我已验证 dbContext.Customers.Local 具有我期望的对象,但它似乎没有提取本地对象。会不会是因为Customer是一个抽象类,由DirectCustomer和InDirectCustomer实现?

为什么?我可以通过配置更改此行为吗?也许我必须合并本地和数据库结果(有点 hacky)。

更新:

class Program
{
static void Main(string[] args)
{
MyDbContext context = new MyDbContext();

Guid customerGuid = Guid.NewGuid();

context.Customers.Add(new DirectCustomer()
{
Id = customerGuid
});

// This does not work, customerFromLocal1 is null
var customerFromLocal1 = context.Customers.FirstOrDefault(x => x.Id == customerGuid);

// This does work, customerFromLocal2 is NOT null
var customerFromLocal2 = context.Customers.Find(customerGuid);


}
}


public class MyDbContext : Microsoft.EntityFrameworkCore.DbContext
{
public DbSet<Customer> Customers { get; set; }


protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("server=.\\sqlexpress;integrated security=true;database=EFCoreDeepDive2");
base.OnConfiguring(optionsBuilder);
}

protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<DirectCustomer>();
builder.Entity<IndirectCustomer>();
}

}

public abstract class Customer
{
public Guid Id { get; set; }
}

public class DirectCustomer : Customer
{

}

public class IndirectCustomer : Customer
{
public Guid ParentCustomerId { get; set; }
}

最佳答案

在 EF Core 中,Linq 运算符(如 FirstOrDefault()、ToList() 等及其在异步中的对应部分)导致针对服务器评估查询。对于查询,服务器数据是真实的来源。如果返回对象已经加载到内存中,它将合并返回对象,但它会先与服务器进行检查。

当您向上下文中添加一个新的实体对象时,该对象存在于 changetracker 中,但它不会保存到服务器,直到您调用 SaveChanges()。因此,在添加实体之后和调用 SaveChanges 之前针对将针对服务器进行评估的任何查询将没有关于新添加的实体的信息,并且不会返回与其相关的任何结果。

如果您试图通过当前上下文实例中的键值查找实体对象,可能已保存也可能未保存,则使用 context.DbSet.Find() 方法(有上下文中还定义了其他变体。Find 方法首先检查 ChangeTracker 以查找对象,该对象包含内存中加载的所有对象和添加/修改的对象。如果找不到,那么它将从服务器加载对象。在你的情况下,因为你想要找到已添加到上下文但未保存的实体,Find 将为您提供预期的结果。

注意:DbSet.Local 包含当前上下文跟踪的 DbSet 类型的所有实体。因此,添加的实体在那里可用,但不能直接在 DbSet 上使用。 DbSet 是 IQueryable 以便允许针对它编写服务器查询。

关于c# - DbContext 不返回本地对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46184937/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com