EF5 Code-First アプローチを使用した最も単純化された形式の状況を次に示します。
public abstract class EntityBase<PK>
{
public PK ID { get; set; }
}
public class Country : EntityBase<string>
{
public string Name { get; set; }
}
public class Address : EntityBase<int>
{
[Required]
public string CountryID { get; set; }
public Country Country { get; set; }
// ... other address properties ...
}
と の間の 1 対多の関係はAddress
、Country
次のようにカスケード削除なしで設定されます。
modelBuilder.Entity<Address>()
.HasRequired(a => a.Country)
.WithMany()
.HasForeignKey(a => a.CountryID)
.WillCascadeOnDelete(false);
SaveChanges
最後に、基になる DbContext を呼び出してデータの変更をアトミックにコミットする CRUD メソッドを備えた汎用ベース リポジトリ クラスがあります。例えば:
public class EFRepository<T, PK> : IRepository<T, PK> where T : EntityBase<PK>
{
//
// ... other methods ...
//
public virtual void Delete(T instance)
{
// ... trigger validations, write to log, etc...
_dbContext.Set<T>().Remove(instance);
try
{
_dbContext.SaveChanges();
}
catch(Exception ex)
{
// ... handle the error ...
}
}
}
パート1:
シナリオ:
var countryRepo = new EFRepository<Country>();
var country = countryRepo.Save(new Country() { ID="??", Name="Test Country" });
var addressRepo = new EFRepository<Address>();
var address = addressRepo.Save(new Address() { Country=country });
countryRepo.Delete(country);
これは依存関係が存在するため失敗するはずAddress
です。ただし、その後、アドレスは null in で終了しますCountryID
。これは が必要なため無効です。そのため、アドレスが分離されていない限り、Address.CountryID
後続のSaveChanges
呼び出しで検証例外がスローされます。
オブジェクトが削除されると、EF5 は最初に上記のようなカスケード削除制約をチェックし、見つからない場合はデータの削除に進むほどスマートになると予想していました。しかし、まったく逆の場合があるようです。
これは正常な動作ですか、それとも何か間違ったことをしていますか?
パート2:
SaveChanges
呼び出しが失敗した後、一部Addresses
は DbContext で無効な状態になり、元の値に復元する必要があります。もちろん、専用のリポジトリ クラスを作成して をオーバーライドすることで、いつでも各エンティティ タイプ ( Country
、State
、など) に対して明示的にこれを行うことができますが、それには時間がかかります。呼び出しが失敗した後、関連するエンティティを適切に回復するための汎用コードを書きたいと思い ます。Order
Delete
SaveChanges
Country
クラスが依存エンティティへのナビゲーション プロパティを定義しているかどうかに関係なく、エンティティ (例: ) がプリンシパルであるすべての関係を取得するには、DbContext に問い合わせる必要があります。
たとえば、プロパティCountry
がないため、DbContext でとAddresses
の間の 1 対多の関係の定義を何らかの方法で見つけ、それを使用して元の値に関連するすべてを復元する必要があります。Country
Address
Addresses
これは可能ですか?