简体   繁体   English

NHibernate插入具有空多对一映射的新记录

[英]NHibernate insert new record with a null many-to-one mapping

I have a Companies table mapped to a Company class and a Websites table mapped to a Website class. 我有一个映射到Company类的Companies表和一个映射到Website类的Websites表。 My Companies table is basically non-moving, however I'm trying to insert a new Website record with the following: 我的公司表基本上是固定不变的,但是我正尝试使用以下内容插入新的网站记录:

var website = new Website
{
    Active = true,
    SiteRoot = "example.com",
    CompanyId = 100     
};
var repo = new WebsiteRepository();
repo.Add(website);

The website class has a CompanyId property which is what maps back to the ID column in the Companies table, but because the Website class has a many-to-one mapping, it's trying to insert the website.Company.Id property into the table(which is null) instead of taking the website.Id property. 网站类具有CompanyId属性,该属性映射回COMPANY表中的ID列,但是由于Website类具有多对一映射,因此它试图将website.Company.Id属性插入表中( (为null),而不是采用website.Id属性。

There are no foreign keys involved as the tables are in 2 separate databases. 由于表位于2个单独的数据库中,因此不涉及外键。

This is the error I'm receiving: 这是我收到的错误:

NHibernate.Exceptions.GenericADOException: could not insert: [Models.Website][SQL: INSERT INTO Database1.dbo.Websites (CompanyID, SiteRoot, Active) VALUES (?, ?, ?); NHibernate.Exceptions.GenericADOException:无法插入:[Models.Website] [SQL:插入到Database1.dbo.Websites(CompanyID,SiteRoot,活动)值(?,?,?); select SCOPE_IDENTITY()] ---> System.Data.SqlClient.SqlException: Cannot insert the value NULL into column 'CompanyID', table 'Database1.dbo.Websites'; 选择SCOPE_IDENTITY()] ---> System.Data.SqlClient.SqlException:无法将值NULL插入表'Database1.dbo.Websites'的'CompanyID'列中; column does not allow nulls. 列不允许为空。 INSERT fails. INSERT失败。

NHibernate: INSERT INTO Database1.dbo.Websites (CompanyID, SiteRoot, Active) VALUES (@p0, @p1, @p2); NHibernate:插入到Database1.dbo.Websites(CompanyID,SiteRoot,活动)值(@ p0,@ p1,@ p2); select SCOPE_IDENTITY();@p0 = NULL [Type: Int32 (0)], @p1 = 'example.com' [Type: String (4000)], @p2 = True [Type: Boolean (0)] 选择SCOPE_IDENTITY(); @ p0 = NULL [类型:Int32(0)],@ p1 ='example.com'[类型:字符串(4000)],@ p2 = True [类型:布尔(0)]

Here are the mappings: 这里是映射:

<hibernate-mapping assembly="Models" namespace="Models" xmlns="urn:nhibernate-mapping-2.2" schema="Database1.dbo">
  <class name="Website" table="Websites" lazy="true" >
    <id name="Id" column="ID">
      <generator class="identity" />
    </id>
    <many-to-one name="Company" column="CompanyID" fetch="join"/>
    <property name="SiteRoot">
      <column name="SiteRoot" sql-type="nvarchar" length="50" not-null="false" />
    </property>
    <property name="Active">
      <column name="Active" sql-type="bit" not-null="true" />
    </property>
  </class>
</hibernate-mapping>

<hibernate-mapping assembly="Models" namespace="Models" xmlns="urn:nhibernate-mapping-2.2" schema="Database2.dbo">
  <class name="Company" table="Companies" lazy="true" >
    <id name="Id" column="ID">
      <generator class="identity" />
    </id>
    <property name="CompanyId">
      <column name="CompanyID" sql-type="int" not-null="true" />
    </property>
    <property name="CompanyName">
      <column name="CompanyName" sql-type="nchar" not-null="false" />
    </property>
    <set name="Websites" table="Websites" schema="Database1.dbo" lazy="false">
      <key column="CID"/>
      <one-to-many class="Models.Website, Models" />
    </set>
  </class>
</hibernate-mapping>

You need to assign a company to the Company property to implement the many-to-one relation. 您需要将公司分配给Company属性,以实现多对一关系。 Something like this: 像这样:

var website = new Website
{
    Active = true,
    SiteRoot = "example.com",
    Company = session.Load(100);
}; 

Or, if you like, use a repository: 或者,如果您愿意,请使用存储库:

var website = new Website
{
    Active = true,
    SiteRoot = "example.com",
    Company = CompanyRepository.Get(100);
}; 

Note: 注意:

  • session.Load doesn't load anything from the database if lazy loading is enabled. 如果启用了延迟加载,则session.Load不会从数据库加载任何内容。 It only creates a proxy. 它仅创建一个代理。 This is very efficient. 这非常有效。 At the end it only creates an INSERT statement for the Website with a foreign key of 100, without loosing the object oriented programming style in your code. 最后,它仅使用100的外键为网站创建INSERT语句,而不会丢失代码中的面向对象编程风格。

  • Never access foreign keys in the class model. 切勿在类模型中访问外键。 Foreign keys are managed by NHibernate and do not exist in an object oriented model. 外键由NHibernate管理,在面向对象的模型中不存在。

通过将多对一映射设置为insert =“ false”和update =“ false”,然后将CompanyId属性添加到网站映射来解决此问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM