保存更改时,如何在 DbContext 中获取正确的 DbSet
本文关键字:DbSet Entity 获取 DbContext 保存更改 | 更新日期: 2023-09-27 18:33:06
我有一个像这样的 DbContext
public class MyContext : DbContext
{
public DbSet<Entity1> Entities1 { get; set; }
public DbSet<Entity2> Entities2 { get; set; }
. . .
}
其中Entity1
和Entity2
继承基类
public abstract class BaseEntity
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
. . .
}
出于某种原因,我需要删除数据库中的自动增量并在上下文中进行自定义自动增量,以避免数据库影响。所以我决定估计Id
列中的当前最大值并增加它。
我创建了一个简单的方法
private int GetMaxId(IQueryable<BaseEntity> set)
{
if (set.Count() == 0) return 0;
else return set.Max(x => x.Id);
}
所以在上下文构造函数中,我做了 folowing:
public MyContext() : base("MyConnection")
{
. . .
var objectContext = ((IObjectContextAdapter)this).ObjectContext;
objectContext.SavingChanges += (sender, args) =>
{
foreach (var entry in ChangeTracker.Entries())
{
var entity = entry.Entity;
var state = entry.State;
if (entity is BaseEntity)
{
switch (entry.State)
{
case EntityState.Added:
var set = Set<entity.GetType()>();
(entity as BaseEntity).Id = GetMaxId(set) + 1;
. . .
}
}
}
ChangeTracker.DetectChanges();
};
. . .
}
但问题是我不能像Set<entity.GetType()>()
那样构造 DbSet,就像Set<typeof(entity)>()
一样 - 它说最后一个)
是无效表达式。虽然它不依赖于括号的数量''顺序。
Set(entity.GetType())
也不适合我,因为它返回一个非类型化的 DbSet。
请告诉我如何解决这个问题或我做错了什么。
您可以使用
以下代码按实体类型获取DbSet
:
var set = Set(entity.GetType());
不能在运行时将类型确定为泛型类型参数。在您的情况下,此解决方法应该有效:
public MyContext() : base("MyConnection")
{
var objectContext = ((IObjectContextAdapter) this).ObjectContext;
objectContext.SavingChanges += (sender, args) =>
{
foreach (var entry in ChangeTracker.Entries())
{
var entity = entry.Entity;
var state = entry.State;
if (entity is BaseEntity)
{
ProcessEntity((BaseEntity)entity, state);
}
}
ChangeTracker.DetectChanges();
};
}
private void ProcessEntity<T>(T entity, EntityState state) where T : BaseEntity
{
switch (state)
{
case EntityState.Added:
var set = Set<T>();
(entity as BaseEntity).Id = GetMaxId(set) + 1;
break;
}
}
在长期为铸造DbSet
而苦苦挣扎后,我终于找到了解决方案。问题是我们不需要铸造DbSet
,我们必须铸造它的元素。
这显然。
因此,GetMaxId
的最终版本(前提是我们在GetMaxId
调用之前检查entity
BaseEntity
)是
private int GetMaxId(DbSet set)
{
int max = 0;
foreach (var item in set)
{
int id = (item as BaseEntity).Id;
if (id > max) max = id;
}
return max;
}
和相应的案例是
case EntityState.Added:
(entity as BaseEntity).Id = GetMaxId(Set(entity.GetType())) + 1;
. . .
就像@alisabzevari说的那样。