C# DbSet<;tenty>;。本地vs DbContext.ChangeTracker
在一次会议上,我要求澄清何时使用C# DbSet<;tenty>;。本地vs DbContext.ChangeTracker,c#,entity-framework,repository,dbcontext,C#,Entity Framework,Repository,Dbcontext,在一次会议上,我要求澄清何时使用DbSet.Local。我还没有得到答案,我想这个问题可能包含了太多的信息。在深入挖掘之后,我可以问一个更具体的问题 希望你们能解释一下在我的场景中选择哪两个选项 我想要实现什么? 我正在尝试从我的存储库中检索实体。实体仍处于“添加”状态(即,我尚未调用SaveChanges方法)。我需要这个,因为我想在一个原子操作中存储实体,所以我必须将SaveChanges调用推迟到我验证完整模型之后 此外,我还需要遵循IQueryable接口,因为我有使用扩展方法Inclu
DbSet.Local
。我还没有得到答案,我想这个问题可能包含了太多的信息。在深入挖掘之后,我可以问一个更具体的问题
希望你们能解释一下在我的场景中选择哪两个选项
我想要实现什么?
存储库
中检索实体。实体仍处于“添加”状态(即,我尚未调用SaveChanges
方法)。我需要这个,因为我想在一个原子操作中存储实体,所以我必须将SaveChanges
调用推迟到我验证完整模型之后Include
onQueryable
来延迟加载导航属性的依赖代码- 通过
属性检索处于“添加”状态的实体DbSet.Local
- 通过
DbContext.ChangeTracker
public void addandRetrieveUncommittedIdentityFromDBContext()
{
SetInitializer(新的DropCreateDatabaseAlways());
var testContext=newtestcontext();
//初始化实体并将其存储在存储库中
var-tenant=new-tenant{Name=“test”,Guid=Guid.NewGuid().ToString()};
var user=新用户{Name=“bas”,EmailAddress=”bas@domain.com,Password=“Password”};
tenant.Users.Add(用户);
testContext.Tenants.Add(租户);
//注意:我还没有调用'SaveChanges',但我仍然想检索
//我的存储库中的租户
///////////////////////////////////////////////
//备选方案一,使用ChangeTracker//
///////////////////////////////////////////////
IEnumerable tenants=testContext.ChangeTracker.Entries();
IQueryable query=tenants.Select(dbEntityEntry=>dbEntityEntry.Entity).AsQueryable();
租户storedTenant=查询。
其中(ent=>ent.Name.Equals(“test”))。
Include(ent=>ent.Users).First();
Assert.IsNotNull(storedTenant.Users.FirstOrDefault());
//万岁,它过去了
///////////////////////////////////////////////
//备选方案二,使用“本地”属性//
///////////////////////////////////////////////
IQueryable query2=testContext.Tenants.Local.AsQueryable();
租户storedTenant2=查询2。
其中(ent=>ent.Name.Equals(“test”))。
Include(ent=>ent.Users).First();
Assert.IsNotNull(storedTenant2.Users.FirstOrDefault());
//万岁,它过去了
////////////////////////////////////////////////
//为了完整性=>实体不在DbSet中//
////////////////////////////////////////////////
IQueryable query3=testContext.Tenants.AsQueryable();
租户存储的Tenant3=查询3。
其中(ent=>ent.Name.Equals(“test”))。
Include(ent=>ent.Users).FirstOrDefault();
Assert.IsNotNull(storedTenant3);
//失败,因为该实体在数据库集“testContext.Tenants”中尚不可用
}
testContext非常简单:
public class TestContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Tenant> Tenants { get; set; }
public TestContext() : base("Test1") {}
}
公共类TestContext:DbContext
{
公共数据库集用户{get;set;}
公共数据库集租户{get;set;}
公共TestContext():基(“Test1”){}
}
问题
- 检索所有实体(即包括处于“添加”状态的实体)的建议方法是什么
和DbSet.Local
的优缺点是什么李>ChangeTracker
非常感谢 这取决于你想做什么。您的代码中没有一个是按
DbEntityEntry.State
进行专门过滤的,因此我假设您确定上下文跟踪的所有实体都处于添加状态
如果您不确定所有被跟踪的实体都处于添加状态,则ChangeTracker
可让您通过EntityState筛选DbEntityEntry
s。添加的
,然后获取对要处理的实际实体的引用
使用Local
可以获得实体本身的可观察集合。如果您确定它们都处于添加状态,那么这可能是最简单的。如果不确定,则必须枚举集合并从上下文中获取DbEntityEntry
,以确保:
foreach(var entity in collection)
{
if(context.entry(entity).State == EntityState.Added)
{
//do stuff...
}
}
如果这些都是为了执行验证,那么还有其他方法可以进行验证,其中一些方法可以阅读。您是否手动生成这些注释(///../code>)?(只是好奇)。是的,这是超级跛脚的,因为当我键入//.thx时,VisualStudio可以帮我做到这一点,为您提供清晰的解释。我不是在寻找“添加的”实体集,而是在寻找我的系统已知的“所有”实体。我希望通过DbSet
返回的内容。因此,我不能完全确定我现在是否有正确的答案。我现在的看法是,我从不需要DbSet
,但我总是需要DbSet.Local
。但话说回来,不是每个人都想检索他们系统已知的所有实体吗?那么我为什么要使用DbSet
。我说的有道理吗,还是我完全错了?谢谢你的帮助+1如果需要跟踪的实体,则可以查询本地集合,但显然仍需要数据库集进行数据库访问。我觉得您的存储库/上下文存在的时间太长了,这就是为什么您在本地和本地之间存在这种困境
foreach(var entity in collection)
{
if(context.entry(entity).State == EntityState.Added)
{
//do stuff...
}
}