我有一个使用 EF5 的项目,我制作了一个自定义 Guid 生成器,并且我重写了 SaveChanges 方法来分配我的实体的 ID。
一切正常,除了在一种情况下:当一个实体的 ID 是另一个实体的另一个 ID 的 FK 时。
一点代码来解释这个问题:
我有两个无法更改的实体:
public class FixedEntityA
{
public Guid Id { get; set;}
public string SomeText { get; set; }
}
public class FixedEntityB
{
public Guid Id { get; set;}
public int OneInt { get; set; }
}
在我的项目中,我有一个这样定义的实体:
public class ComposedEntity
{
public Guid Id { get; set;}
public FixedEntityA FixedA { get; set; }
public FixedEntityB FixedB { get; set; }
public double OneDouble { get; set; }
}
关系是:
ComposedEntity 可能有 0 或 1 个 FixedEntityA
ComposedEntity 可能有 0 或 1 个 FixedEntityB
对 id 的约束是:
FixedEntityA 的 Id 是指向 ComposedEntity 的 Id 的 FK
FixedEntityB 的 Id 是指向 ComposedEntity 的 Id 的 FK
映射类是:
public ComposedEntity(): EntityTypeConfiguration<ComposedEntity>
{
HasOptional(fea => fea.FixedA).WithRequired();
HasOptional(feb => feb.FixedB).WithRequired();
}
这是我的 SaveChanges 覆盖:
foreach (var entry in ChangeTracker.Entries<IEntity>().Where(e => e.State == EntityState.Added))
{
Type t = entry.Entity.GetType();
List<DatabaseGeneratedAttribute> info = t.GetProperty("Id")
.GetCustomAttributes(typeof (DatabaseGeneratedAttribute), true)
.Cast<DatabaseGeneratedAttribute>().ToList();
if (!info.Any() || info.Single().DatabaseGeneratedOption != DatabaseGeneratedOption.Identity)
{
if (entry.Entity.Id == Guid.Empty)
entry.Entity.Id = (Guid) _idGenerator.Generate();
}
}
return base.SaveChanges();
此代码适用于所有类型的关系,除了在这种情况下,我错过了一个测试,以确保我没有在作为外键的 id 上设置 id,并且我不知道如何检查 Id 是否是一个FK...
这是此代码失败的示例对象:
var fea = new FixedEntityA();
var feb = new FixedEntityB();
var composedEntity = new ComposedEntity();
composedEntity.FixedA = fea;
composedEntity.FixedB = feb;
如果插入整个图形,所有三个对象都标记为已添加,并且所有 Id 都是默认值。
问题是,使用当前的 SaveChanges 方法,我将遍历更改跟踪器中具有已添加状态的所有对象,并且我将为具有默认 Guid 的所有实体分配一个 Id 并打破我的 FK 约束。
提前谢谢各位!