NHibernate - 问号而不是查询中的值

时间:2015-08-10 13:22:49

标签: c# mysql asp.net nhibernate

基本上我有一个Topic对象,可以有多个Category与之关联。我正在尝试向特定的Category插入新的Topic,但我收到错误。

在前端使用ASP.NET 4windows-1255编码,ASPhebrew_bin MySQL(后端)< / p>

ISession session = dal.GetSession();
using (session.BeginTransaction())
{
    Topic t = session.Get<Topic>(topicId);
    Category c = new Category() { Name=name };
    t.AddCategory(c); // updates both references (inside `t` and inside `c`)
    session.Update(t);
    session.Save(c);
    session.Transaction.Commit();
}

获取错误:

  

无法插入:[DAL.Models.Category#1] [SQL:INSERT INTO类别(名称,发布,主题ID,ID)值(?,?,?,?)]

最终由于违反外键约束而失败(我猜?不是有效的ID):

  

无法添加或更新子行:外键约束失败(etladaatdbcategory,CONSTRAINT FK6482F249B6E2851 FOREIGN KEY(ID)参考topicID))

Topic.cs:

public enum ColorEnum { Blue, Red, Green, Yellow }
    public class Topic
    {
        public virtual int ID { get; set; }
        public virtual string Name { get; set; }
        public virtual string Description { get; set; }
        public virtual string ImageUri { get; set; }
        public virtual ColorEnum Color { get; set; }

        public virtual IList<Category> Categories { get; set; }

        public virtual void AddCategory(Category c)
        {
            Categories.Add(c);
            c.Topic = this;
        }
    }

Topic.hbm.xml:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="DAL"
                   namespace="DAL.Models">
  <class name="Topic" lazy="true">
    <id name="ID">
      <generator class="increment"></generator>
    </id>
    <property name="Name" />
    <property name="Description" />
    <property name="ImageUri" />
    <property name="Color" type="ColorEnum" />

    <bag name="Categories" lazy="true" inverse="true"
                         batch-size="25" cascade="all-delete-orphan">
      <key column="ID" />
      <one-to-many class="Category" />
    </bag>
  </class>
</hibernate-mapping>

Category.cs:

public class Category
    {
        public virtual int ID { get; set; }
        public virtual string Name { get; set; }
        public virtual bool Publish { get; set; }

        public virtual Topic Topic { get; set; }
    }

Category.hbm.xml:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="DAL"
                   namespace="DAL.Models">
  <class name="Category" lazy="true">
    <id name="ID">
      <generator class="increment"></generator>
    </id>
    <property name="Name"/>
    <property name="Publish" />

    <many-to-one name="Topic" class="Topic" column="TopicID" />
  </class>
</hibernate-mapping>

2 个答案:

答案 0 :(得分:1)

看起来,您似乎错过了将主题分配到类别。所以这应该做到这一点:

// original
Category c = new Category() { Name=name };
t.AddCategory(c);
// always assign both sides during creation
c.Topic = t;

现在NHibernate将知道引用的 Topic ...并将插入正确的 ID

关于映射。多对一和一对多的关系仅由一列表示。它是子(类别)表中的外键列 - TopicID

所以这是正确的映射:

// Topic
<bag name="Categories" lazy="true" inverse="true"
                     batch-size="25" cascade="all-delete-orphan">
  // this is wrong
  // <key column="ID" />
  // this is the target column in the other table
  <key column="TopicID" />
  <one-to-many class="Category" />
</bag>

...

// Category
// the same columns for the same relation
<many-to-one name="Topic" class="Topic" column="TopicID" />

有了级联,我们可以保存主题:

session.Update(t);
// not needed, there is a cascade
// session.Save(c);

答案 1 :(得分:0)

我认为您的实体不完整,您应该更改您的代码。 不要忘记对using个对象使用IDisposable语句。

using(ISession session = dal.GetSession())
{
using (session.BeginTransaction())
{
    Topic t = session.Get<Topic>(topicId);
    Category c = new Category() { Name=name };
    t.AddCategory(c);
    c.Topic = t;
    session.SaveOrUpdate(t);
    session.Transaction.Commit();
}
}

您也可以使用t.AddCategory(c);方法:

public void AddCategory(Category category)
{
  // add to list
  category.Topic = this;
}