2

私は一対多のマッピングをしています。1:N の 2 つのテーブルに永続化されたコレクションを持つエンティティ

これはクラスとマッピングです:

public class Test
    {
        public virtual string Id { get; set; }
        public virtual string Description { get; set; }
        public virtual IList<TestItem> Items { get; set; }

        public Test()
        {
            Items = new List<TestItem>();
        }
    }

    public class TestItem
    {
        public virtual string Id { get; set; }
        public virtual Test Test { get; set; }
        public virtual string ItemCode { get; set; }
        public virtual string ItemData { get; set; }
    }

    public class TestMap : ClassMapping<Test>
    {
        public TestMap()
        {
            Id(x => x.Id, m => m.Column("IDTest"));

            Bag(x => x.Items, c =>
            {
                c.Key(k =>
                {
                    k.NotNullable(true);
                    k.Column("IDTest");
                });
                c.Cascade(Cascade.DeleteOrphans);
                c.Lazy(CollectionLazy.NoLazy);
                c.Inverse(true);
            }, r => r.OneToMany(m =>
            {
                m.NotFound(NotFoundMode.Exception);
                m.Class(typeof(TestItem));
            }));
        }
    }

    public class TestItemMap : ClassMapping<TestItem>
    {
        public TestItemMap()
        {
            Id(x => x.Id, m => m.Column("IDTestItem"));

            ManyToOne(x => x.Test, m =>
            {
                m.Column("IDTest");
                m.NotNullable(false);
                m.Lazy(LazyRelation.NoLazy);
            });

            Property(x => x.ItemCode);
            Property(x => x.ItemData);
        }
    }

そしてこれがコードです。マークされた行を削除すると、エラーが発生します。

var session = SessionFactory.OpenSession();

            using (var tr = session.BeginTransaction())
            {
                var test = new Test();
                test.Id = "T01";
                test.Description = "Desc TEST 01";

                session.SaveOrUpdate(test); // If Removed Get INSERT ERROR on TestItem

                var item = new TestItem { Id = "NEW01", ItemCode = "A", Test = test, ItemData = "New T01A" };
                test.Items.Add(item);
                session.SaveOrUpdate(item);

                session.SaveOrUpdate(test);

                tr.Commit();
            }

私の質問は:

これは「1対多」の関係を維持するためのベストプラクティスですか?

以下のコードを使用して、ヘッダー行 (テスト) のみを保存し、すべての挿入を子テーブルに自動的にカスケードしてすべて保存することは可能ですか??

var session = SessionFactory.OpenSession();

            using (var tr = session.BeginTransaction())
            {
                var test = new Test();
                test.Id = "T01";
                test.Description = "Desc TEST 01";

                //session.SaveOrUpdate(test); // If Removed Get INSERT ERROR on TestItem

                var item = new TestItem { Id = "NEW01", ItemCode = "A", Test = test, ItemData = "New T01A" };
                test.Items.Add(item);
                //session.SaveOrUpdate(item);

                session.SaveOrUpdate(test);

                tr.Commit();
            }

マッピングコードで何かを変更する必要があると思いますが、何がわかりません!!!

何日もの作業、グーグル、スタックオーバーフローですが、結果は何も変わりません。

ありがとうございました!!!

4

1 に答える 1

2

Q:これは「1 対多」の関係を維持するためのベスト プラクティスですか?

A: 「構成」関係について話している場合は、カスケード アプローチが適切な選択になる可能性があります。

Q:以下のコードを使用して、ヘッダー行 (テスト) のみをすべて保存し、すべての挿入を子テーブルに自動的にカスケードすることは可能ですか??

A: はい、可能です。ただし、コードは次のようになります。

public class TestMap : ClassMapping<Test>
{
    public TestMap()
    {
        Id(x => x.Id, m => m.Column("IDTest"));

        Bag(x => x.Items, c =>
        {
            c.Key(k =>
            {
                k.NotNullable(true);
                k.Column("IDTest");
            });
            c.Cascade(Cascade.All | Cascade.DeleteOrphans); //<- My suggestion
            c.Lazy(CollectionLazy.NoLazy);
            c.Inverse(true);
        }, r => r.OneToMany(m =>
        {
            m.NotFound(NotFoundMode.Exception);
            m.Class(typeof(TestItem));
        }));
    }
}
于 2012-07-17T21:01:34.663 に答える