1

EF5を使用しているプロジェクトがあり、カスタムGUIDジェネレーターを作成し、エンティティのIDを割り当てるためにSaveChangesメソッドをオーバーライドしています。

あるエンティティのIDが別のエンティティの別のIDへのFKである場合を除いて、すべてが正常に機能しています。

問題を説明するための少しのコード:

変更できないエンティティが2つあります。

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;

グラフ全体を挿入すると、3つのオブジェクトすべてが追加としてマークされ、すべてのIDがデフォルトになります。

問題は、現在のSaveChangesメソッドを使用して、変更トラッカーで追加状態のすべてのオブジェクトを調べ、デフォルトのGUIDを使用してすべてのエンティティにIDを割り当て、FK制約を解除することです。

よろしくお願いします!

4

1 に答える 1

2

これは、特定のタイプの FK プロパティを取得するコードです (私が知っている恐ろしいことです)。これをコードにプラグインするのに十分単純でなければなりません。

var typeName = "Category";

var fkProperties = ((IObjectContextAdapter)db)
    .ObjectContext
    .MetadataWorkspace
    .GetItems<AssociationType>(DataSpace.CSpace)
    .Where(a => a.IsForeignKey)
    .Select(a => a.ReferentialConstraints.Single())
    .Where(c => c.FromRole.GetEntityType().Name == typeName)
    .SelectMany(c => c.FromProperties)
    .Select(p => p.Name);
于 2013-04-09T23:36:52.270 に答える