ここに、私があなたがやろうとしていることをする例があります。あなたがしようとしていることを誤解しているかどうか教えてください。次のマッピングで
public class Person
{
private IList<Pet> pets;
protected Person()
{ }
public Person(string name)
{
Name = name;
pets = new List<Pet>();
}
public virtual Guid Id { get; set; }
public virtual string Name { get; set; }
public virtual IEnumerable<Pet> Pets
{
get { return pets; }
}
public virtual void AddPet(Pet pet)
{
pets.Add(pet);
}
public virtual void RemovePet(Pet pet)
{
pets.Remove(pet);
}
}
public class Pet
{
protected Pet()
{ }
public Pet(string name)
{
Name = name;
}
public virtual Guid Id { get; set; }
public virtual string Name { get; set; }
}
:
public class PersonMap : ClassMap<Person>
{
public PersonMap()
{
LazyLoad();
Id(x => x.Id).GeneratedBy.GuidComb();
Map(x => x.Name);
HasMany(x => x.Pets)
.Cascade.AllDeleteOrphan()
.Access.AsLowerCaseField()
.SetAttribute("lazy", "false");
}
}
public class PetMap : ClassMap<Pet>
{
public PetMap()
{
Id(x => x.Id).GeneratedBy.GuidComb();
Map(x => x.Name);
}
}
このテスト:
[Test]
public void CanDeleteChildren()
{
Person person = new Person("joe");
Pet dog = new Pet("dog");
Pet cat = new Pet("cat");
person.AddPet(dog);
person.AddPet(cat);
Repository.Save(person);
UnitOfWork.Commit();
CreateSession();
UnitOfWork.BeginTransaction();
Person retrievedPerson = Repository.Get<Person>(person.Id);
Repository.Evict(retrievedPerson);
retrievedPerson.Name = "Evicted";
Assert.AreEqual(2, retrievedPerson.Pets.Count());
retrievedPerson.RemovePet(retrievedPerson.Pets.First());
Assert.AreEqual(1, retrievedPerson.Pets.Count());
Repository.Save(retrievedPerson);
UnitOfWork.Commit();
CreateSession();
UnitOfWork.BeginTransaction();
retrievedPerson = Repository.Get<Person>(person.Id);
Assert.AreEqual(1, retrievedPerson.Pets.Count());
}
実行され、次のSQLを生成します。
以下 "ドメイン" のクラスを考えると
DeletingChildrenOfEvictedObject.CanDeleteChildren:Passed NHibernate:INSERT INTO [Person](名前、ID)VALUES(@ p0、@ p1); @ p0 = 'joe'、@ p1 = 'cd123fc8-6163-42a5-aeeb-9bf801013ab2'
NHibernate:INSERT INTO [ペット](名前、ID)VALUES(@ p0、@ p1); @ p0 = 'dog'、@ p1 = '464e59c7-74d0-4317-9c22-9bf801013abb'
NHibernate:INSERT INTO [ペット](名前、ID)VALUES(@ p0、@ p1); @ p0 = 'cat'、@ p1 = '010c2fd9-59c4-4e66-94fb-9bf801013abb'
NHibernate:UPDATE [ペット] SET Person_id = @ p0 WHERE Id = @ p1; @ P0 = 'cd123fc8-6163-42a5-aeeb-9bf801013ab2'、@ P1 = '464e59c7-74d0-4317-9c22-9bf801013abb'
NHibernateは:UPDATE [ペット] SET PERSON_ID = @ P0 ID = @ P1。 @ P0 = 'cd123fc8-6163-42a5-aeeb-9bf801013ab2'、@ P1 = '010c2fd9-59c4-4e66-94fb-9bf801013abb'
NHibernateは:[人から人Name5_0_としてId5_0_、person0_.Nameとしてperson0_.Idを選択] person0_どこに[email protected]; @ P0 = 'cd123fc8-6163-42a5-aeeb-9bf801013ab2'
NHibernateは:Person3_1_、Id1_としてpets0_.Id、Id6_0_としてpets0_.Id、pets0_.Name Name6_0_としてFROM [ペット] pets0_としてpets0_.Person_idを選択[email protected]; @ p0 = 'cd123fc8-6163-42a5-aeeb-9bf801013ab2'
NHibernate:UPDATE [Person] SET Name = @ p0 WHERE Id = @ p1; @P0 = 'Evicted'、@ p1 = 'cd123fc8-6163-42a5-aeeb-9bf801013ab2'
NHibernate:UPDATE [ペット] SET名= @ p0 WHERE Id = @ p1; @ p0 = 'dog'、@ p1 = '464e59c7-74d0-4317-9c22-9bf801013abb' NHibernate:UPDATE [ペット] SET Person_id = null WHERE Person_id = @ p0 AND Id = @ p1; @ P0 = 'cd123fc8-6163-42a5-aeeb-9bf801013ab2'、@ P1 = '010c2fd9-59c4-4e66-94fb-9bf801013abb'
NHibernateは:[ペット] ID = @ P0から削除します。 @ P0 = '010c2fd9-59c4-4e66-94fb-9bf801013abb'
NHibernateは:Id5_0_、FROM Name5_0_としてperson0_.Name [人] person0_ [email protected]としてperson0_.Idを選択します。 @ P0 = 'cd123fc8-6163-42a5-aeeb-9bf801013ab2'
NHibernateは:Person3_1_、Id1_としてpets0_.Id、Id6_0_としてpets0_.Id、pets0_.Name Name6_0_としてFROM [ペット] pets0_としてpets0_.Person_idを選択[email protected];あなたが行うことができるために必要なもの@ P0 = 'cd123fc8-6163-42a5-aeeb-9bf801013ab2' [ペット]。DELETE FROM
注...そう
は、手NHibernateはPersonオブジェクト(ですこの例)を変更したコレクションで置き換え、削除するものを決定できるはずです。 Cascade.AllDeleteOrphan()属性が設定されていることを確認してください。
非常にありがとうございます - そこに多くの作業!残念ながら、私が苦労しているのは、2番目のセッション/トランザクション(すなわち私のPOST)で持っている 'Person'オブジェクトが、ModelBinderによって作成されたまったく新しいオブジェクトであり、いくつかのフィールドが変更され、少数の「子を削除」の呼び出しが行われました。私が探しているのは、新しいオブジェクトを取得し、その変更を取得したオブジェクトに適用して、nhが必要なSQLを処理できる方法だと思います。たぶんそれは存在しないかもしれません。 –
私がその状況に対処する方法は、モデルバインダーによって作成された新しいオブジェクトをプレゼンテーションモデルオブジェクトとして扱うことです。更新してそのオブジェクトに更新を適用するオブジェクトを取得する(または、何らかの形で "永続化"クラスのインスタンスを作成する)必要があります。その後、そのオブジェクトをNHibernateに保存することができます。それは理にかなっていますか? –
「手動」(つまり、プロパティ別、ループなど、子コレクションのもの)は、 '取り出した'オブジェクトのプロパティを 'プレゼンテーション(つまりPOST)'オブジェクトのプロパティで上書きしますか?必要な子の削除を手動で計算しますか?私が望んでいたよりももう少し仕事があるようです(そして、維持!)。モデルバインダーでは迷惑になるようなことはほとんどありませんが、実際にはフィールドを1つずつ処理しなければならないかのように、フォームレスポンスから直接引き出すことができます。しかし、助けてくれてありがとう。 –