Nhibernate:一对多关系导致GenericADOException

时间:2013-02-22 00:02:25

标签: nhibernate

我遇到以下异常,我很确定它与类别和产品之间的一对多关系有关。怎么了?

Nhibernate.Exceptions.GenericADOException {“无法执行批处理命令。[SQL:SQL不可用]”}

的InnerException: {“INSERT语句与FOREIGN KEY约束冲突\”FK1F94D86A1B57B09E \“。冲突发生在数据库\”SimpleNhibernate \“,table \”dbo.Category \“,列'Id'。\ r \ n语句已终止。“}

Program.cs的

class Program
{
    private static ISessionFactory _sessionFactory;
    private static Configuration _configuration;

    static void Main(string[] args)
    {

        _configuration = new Configuration();
        _configuration.Configure();
        _configuration.AddAssembly(typeof(Product).Assembly);
        _sessionFactory = _configuration.BuildSessionFactory();

        var schema = new SchemaExport(_configuration);
        schema.Drop(true, true);
        schema.Create(true, true);

        AddCategory(new Category("Phone"));
        AddCategory(new Category("Smart Phone"));

        using (ISession session = NHibernateHelper.OpenSession())
        {
            var categories = session.QueryOver<Category>().List();                
            foreach (var category in categories)
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    session.Save(new Product("iPhone", category));      
                    transaction.Commit(); 


                }
            }
        }

    }

    private static void AddCategory(Category product)
    {
        using (ISession session = NHibernateHelper.OpenSession())
        using (ITransaction transaction = session.BeginTransaction())
        {
            session.Save(product);
            transaction.Commit();
        }
    }
}

Category.cs

using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Iesi.Collections.Generic;
namespace SimpleNhibernate
{
    public class Category
    {
        public virtual Guid Id { get; set; }
        public virtual string Name { get; set; }
        public virtual ISet<Product> Products { get; set; }
        public virtual bool Discontinued { get; set; }

        public Category() { }

        public Category(string name)
        {
            Name = name;
        }
    }
}

Category.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="SimpleNhibernate"
                   namespace="SimpleNhibernate">

  <class name="Category">
    <id name="Id">
      <generator class="guid" />
    </id>
    <property name="Name" />
    <set name="Products" inverse="true" >
      <key column="Id" />
      <one-to-many class="Product"/>
    </set>
    <property name="Discontinued" />
  </class>

</hibernate-mapping>

Product.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
                   assembly="SimpleNhibernate" 
                   namespace="SimpleNhibernate">

  <class name="Product">
    <id name="Id">
      <generator class="guid" />
    </id>
    <property name="Name" />
    <many-to-one name="Category" column="CategoryID"></many-to-one>
    <property name="Discontinued" />
  </class>

</hibernate-mapping>

Product.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SimpleNhibernate
{
    public class Product
    {
        public virtual Guid Id { get; set; }
        public virtual string Name { get; set; }
        public virtual Category Category { get; set; }
        public virtual bool Discontinued { get; set; }

        public Product() { }
        public Product(string name, Category category)
        {
            Name = name;
            Category = category;
        }
    }
}

1 个答案:

答案 0 :(得分:2)

负责映射(两个方向)的列是产品表中的CategoryID

所以set应该有关键字

 <class name="Category">
    ...
    <set name="Products" inverse="true" >
      <key column="CategoryID" /> // instead of Id

与产品映射中的相同

<many-to-one name="Category" column="CategoryID"></many-to-one>