2015-04-18 69 views
1

類:NHibernate的IList的映射,子子表

[DataContract] 
public class Parent 
{ 
    public virtual long Id { get; set; } 

    public virtual string Name { get; set; } 

    [DataMember] 
    public virtual IList<string> Values { get; set; } 

    public Parent() 
    { 

    } 
} 

ORM映射文件:

<class name="Testing.Models.Parent" table="Parent" > 
    <id name="Id"> 
     <generator class="native" /> 
    </id> 
    <property name="Name" /> 
    <list name="Values" table="ChildValue" inverse="true" > 
     <key column="ParentId" /> 
     <index column="Sequence" type="System.Int32"/> 
     <element column="Value" type="System.String"/> 
    </list> 
</class> 

不過,雖然有保存父實體,它只是插入到父表測試。 雖然我提供了值,但未插入任何記錄的ChildValue表。

我發現某處反相必須是真的,即使它不工作。

[更新:插入代碼] 創建方法

public IList<Parent> Create(IList<Parent> entities) 
{ 
using (ISession session = SessionFactory.OpenSession()) 
    { 
     foreach (var entity in entities) 
     { 
      session.Save(entity); 
     } 
     return entities; 
    } 
} 

ISessionFactory使用統一注入並配置爲

UnityContainer.RegisterInstance(typeof(ISessionFactory), 
       new NHibernate.Cfg.Configuration().Configure().BuildSessionFactory()); 

雖然NHibernate的配置是這樣(在app.config)中

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" > 
    <session-factory> 
     <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property> 
     <property name="dialect">NHibernate.Dialect.MsSql2012Dialect,NHibernate</property> 
     <property name="connection.connection_string_name">db</property> 
     <!-- set show_sql property to false on production--> 
     <property name="show_sql">true</property> 
     <mapping assembly="Testing"/> 
    </session-factory> 
    </hibernate-configuration> 

創建實體的測試方法是

[TestMethod] 
     public void TestCreate() 
     { 
      IList<Parent> entities = new List<Parent>(); 
      for (int index = 0; index < 5; index++) 
      { 
       var entity = TestHelper.CreateEntity<Parent>(); 
       entity.Values = new List<string>(); 
       entity.Values.Add("Values" + index); 
       entities.Add(entity); 
      } 
      entities = instance.Create(entities); 

      VerifyPickList(entities, "Create"); 

      Assert.AreEqual(5, (int)TestHelper.Execute("SELECT COUNT(*) FROM" + 
       " [dbo].[Parent]"), "Create is wrong."); 
     } 

[更新2:SQL]

-- parent table 
CREATE TABLE [dbo].[Parent](
    [Id] [int] IDENTITY(1,1) NOT NULL PRimary Key, 
    [Name] [varchar](45) NOT NULL, 
) 

-- child table 
CREATE TABLE [dbo].[ChildValue](
    [ParentId] [int] NOT NULL, 
    [Value] [varchar](45) NOT NULL, 
    [Sequence] [int] NOT NULL, 
CONSTRAINT [PK__Parent__D099C8FD03317E3D] PRIMARY KEY CLUSTERED 
(
    [ParentId] ASC, 
    [Value] ASC 
) 


ALTER TABLE [dbo].[ChildValue] WITH CHECK ADD CONSTRAINT [pk_plv_pl] FOREIGN KEY([ParentId]) 
REFERENCES [dbo].[Parent] ([Id]) 
GO 

ALTER TABLE [dbo].[ChildValue] CHECK CONSTRAINT [pk_plv_pl] 
GO 

回答

1

最重要的這裏是使用inverse="true"

<list name="Values" table="ChildValue" 
    // inverse="true" is NO OPTION for element lists 
    inverse="false" // inverse="false" or nothing 
    > 
    <key column="ParentId" /> 
    <index column="Sequence" type="System.Int32"/> 
    <element column="Value" type="System.String"/> 
</list> 

的一點是,NHibernate的需要將此設置爲:「另一端將關心持久......」,這是確定的,如果有一個班,<one-to-many>。但不正常,如果有<element>

類(映射爲one-to-many是第一層次的公民,可以關心持久... 不能

此代碼現在應該怎麼辦INSERT到這兩個表:

var parent = Parent { Name = "abc" }; 
parent.Values = new List<string> { "testValue" }; 
session.Save(parent); 

檢查文檔,例如

一個例子:

<set name="Aliases" table="person_aliases" sort="natural"> 
    <key column="person"/> 
    <element column="name" type="String"/> 
</set> 

檢查這篇文章的詳細信息:

+0

雅試過了,看了一下,即使沒有設置或inverse = false後,也沒有保存在子表中。(使用log4Net)由Nhibernate生成的sql只有一個查詢插入父表中沒有別的。 – veshu

+0

你能否用你正在用來創建和堅持實體的聲明來擴展你的問題? –

+0

是的,檢查inverse =「false」,沒有包括cascade =「all」。我已經檢查了這些的所有可能的組合。等待好的迴應。非常感謝你的時間。 – veshu