Nibernate BLIKENT (مع تلقائي) عدم حفظ قيم جدول الانضمام في العديد من

StackOverflow https://stackoverflow.com/questions/2028905

سؤال

أنا لست بالضبط خبير أحمق، لذلك قد يكون هذا الافتقار إلى الفهم في تلك القسم. لدي كيانات بسيطة مع علاقة كثيرة كثيرة

public class Category
{
    public virtual int Id { get; private set; }
    public virtual string Name { get; set; }
    public virtual string Description { get; set; }
    public virtual bool Visible { get; set; }

    public virtual IList<Product> Products { get; set; }
}

و

public class Product
{
    public virtual int Id { get; private set; }
    public virtual string Name { get; set; }
    public virtual string Description { get; set; }
    public virtual decimal Price { get; set; }
    public virtual bool Visible { get; set; }
    public virtual IList<Category> Categories { get; set; }
}

التكوين الخاص بي هو

    public static void BuildFactory()
    {
        _factory = Fluently.Configure()
            .Database(
                MsSqlConfiguration
                    .MsSql2008
                    .ConnectionString(_connectionString)
                    .ShowSql()
            )
            .Mappings(m =>
                m.AutoMappings.Add(
                    AutoMap.AssemblyOf<Database>()
                        .Where(t => t.Namespace == "FancyStore.Models.Catalog")
                        .Override<Product>(k => 
                            k.HasManyToMany(x => x.Categories)
                                .Table("ProductsToCategories")
                                    .ParentKeyColumn("Product_id")
                                    .ChildKeyColumn("Category_id")
                                .Cascade.AllDeleteOrphan())
                        .Override<Category>(k =>
                            k.HasManyToMany(x => x.Products)
                                .Table("ProductsToCategories")
                                    .ParentKeyColumn("Category_id")
                                    .ChildKeyColumn("Product_id")
                                .Cascade.AllDeleteOrphan().Inverse())
                )
            )
            .ExposeConfiguration(SetConfiguration)
            .BuildConfiguration()
            .BuildSessionFactory();
    }

لذلك بدأت دون التجاوزات (إضافتها في وقت لاحق بعد أن اقترح بعض googling ذلك)، وأتول على مخططي مع الصادرات. يعلم ExportSchema عن العديد من العلاقات بالنسبة للعديد من العلاقات (حتى بدون تجاوزات)، لأنه ولدت جدول الانضمام (ProductsToCategories).

أردت إضافة بعض بيانات الاختبار البسيطة، لذلك فعلت ذلك مثل هذا

        using (var db = new Repository<Category>())
        {
            for (int i = 0; i < 6; i++)
            {
                var cat = new Category
                {
                    Name = "Things" + i,
                    Description = "Things that are things",
                    Visible = true,
                    Products = new List<Product>()
                };

                for (int k = 0; k < 6; k++)
                {
                    var prod = new Product
                    {
                        Name = "Product" + k,
                        Description = "Product for " + cat.Name,
                        Visible = true,
                        Categories = new List<Category>(new[] { cat })
                    };
                    cat.Products.Add(prod);
                }
                db.Save(cat);
            }
        }

هذا يوفر المنتجات والفئات بشكل صحيح، لكنه لا ينقذ أي من العلاقات في جدول الانضمام. النظر في SQL مكالمة إلى الفئة. ينشئ المنتجات، فإنه يبحث في الواقع في جدول الانضمام للمنتجات (ولا يمكن العثور عليه، لأنه فارغ)

أي مساعدة سيكون موضع تقدير كبير :-)

تعديل: إزالتها معكوس، لا تزال المشكلة تحدث :(

Edit2.:

فيما يلي ملفات رسم الخرائط للكتالوج والمنتج (ملاحظة: الاسم هو نوع من سخيف، ولكن هذا مجرد نوع من الصفقة النموذجي السريع

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true">
  <class xmlns="urn:nhibernate-mapping-2.2" name="FancyStore.Models.Catalog.Product, FancyStore, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`Product`">
    <id name="Id" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Id" />
      <generator class="identity" />
    </id>
    <property name="Name" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Name" />
    </property>
    <property name="Description" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Description" />
    </property>
    <property name="Price" type="System.Decimal, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Price" />
    </property>
    <property name="Visible" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Visible" />
    </property>
    <bag cascade="all-delete-orphan" inverse="true" name="Categories" table="ProductsToCategories">
      <key>
        <column name="Product_id" />
      </key>
      <many-to-many class="FancyStore.Models.Catalog.Category, FancyStore, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
        <column name="Category_id" />
      </many-to-many>
    </bag>
  </class>
</hibernate-mapping>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true">
  <class xmlns="urn:nhibernate-mapping-2.2" name="FancyStore.Models.Catalog.Category, FancyStore, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`Category`">
    <id name="Id" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Id" />
      <generator class="identity" />
    </id>
    <property name="Name" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Name" />
    </property>
    <property name="Description" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Description" />
    </property>
    <property name="Visible" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Visible" />
    </property>
    <bag cascade="all-delete-orphan" name="Products" table="ProductsToCategories">
      <key>
        <column name="Category_id" />
      </key>
      <many-to-many class="FancyStore.Models.Catalog.Product, FancyStore, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
        <column name="Product_id" />
      </many-to-many>
    </bag>
  </class>
</hibernate-mapping>
هل كانت مفيدة؟

المحلول 2

matt briggs، لقد احسبت بها. يجب عليك تعيين علاقة واحدة على أنها معكوس () وحفظ الكيان الآخر، وإضافة مراجع إلى كلا الكيانات (Prod.Categories.Add () + Cat.Products.Add ()) وارتكاب المعاملة. إلا إذا كنت تلتزم الاستعلام لن يتم إنشاء جدول الصلة. - الثقيلة 13 مايو في الساعة 12:43

نصائح أخرى

قد أكون مخطئا، لكن يبدو أنك تحمل العلاقة بأنها "معكوس" لكلا الجانبين.

يجب عليك القيام بذلك لفترة واحدة فقط من العلاقة، وتأكد من الاتصال Save على الآخر.

أيضا، أعتقد أن العلاقة تحتاج إلى صالحة على كلا الجانبين قبل حفظ (إضافة cat ل prod.Categories, بالإضافة إلى ما تفعله بالفعل).

إن فهمي لهذه الأنواع من العلاقات أمر غامض، لكن هذا ما حدث بحثي خلال الأشهر (وحل بعض مشاكلي الخاصة).

لديك معكوس على الجانب الخطأ من الجمعية. معكوس يعني "الجانب الآخر يدير هذه الجمعية".

ما تحتاجه هو إما لإزالة عكس الفئة ووضعه على المنتج، أو تغيير المنتج ليكون كيان "امتلاك"، مثل هذا:

//make sure to add it to BOTH sides of the association
product.Categories.Add(cat);
cat.Products.Add(product);

db.Save(cat);  //if Product has Inverse
/* or */
db.Save(prod); //if Category has Inverse

ماذا عن إذا كنت تقوم بتطبيق التعيينات بطلاقة للمنتج والفئة أولا، قبل السيارات. علي سبيل المثال،

public class Product
{
    public virtual int Id { get; private set; }
    public virtual string Name { get; set; }
    public virtual string Description { get; set; }
    public virtual decimal Price { get; set; }
    public virtual bool Visible { get; set; }
    public virtual IList<Category> Categories { get; set; }

    public Product()
    {
        Categories = new List<Category>();
    }
}

public class ProductMap : ClassMap<Product>
{
    Id(x => x.Id);
    Map(x => x.Name);
    Map(x => x.Description);
    Map(x => x.Price);
    Map(x => x.Visible);
    HasManyToMany(x => x.Categories)
      .Table("ProductsToCategories")
      .ParentKeyColumn("Product_id")
      .ChildKeyColumn("Category_id")
      .Cascade.AllDeleteOrphan();
}

public class Category
{
    public virtual int Id { get; private set; }
    public virtual string Name { get; set; }
    public virtual string Description { get; set; }
    public virtual bool Visible { get; set; }
    public virtual IList<Product> Products { get; set; }

    public Category()
    {
        Products = new List<Product>();
    }
}

public class CategoryMap : ClassMap<Category>
{
    Id(x => x.Id);
    Map(x => x.Name);
    Map(x => x.Description);
    Map(x => x.Visible);
    HasManyToMany(x => x.Products)
      .Table("ProductsToCategories")
      .ParentKeyColumn("Category_id")
      .ChildKeyColumn("Product_id")
      .Cascade.AllDeleteOrphan().Inverse();
}

مع التكوين،

public static void BuildFactory()
{
    _factory = Fluently.Configure()
        .Database(
            MsSqlConfiguration
                .MsSql2008
                .ConnectionString(_connectionString)
                .ShowSql()
        )
        .Mappings(m => {
            m.FluentMappings.AddFromAssemblyOf<Database>();
            m.AutoMappings.Add(
              AutoMap.AssemblyOf<Database>()
              .Where(t => t.Namespace == "FancyStore.Models.Catalog"));
        })
        .ExposeConfiguration(SetConfiguration)
        .BuildConfiguration()
        .BuildSessionFactory();
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top