Nhibernate IList 映射到子子 table
Nhibernate IList mapping to sub child table
Class:
[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>
但是在测试父实体的保存时,它只插入父实体 table。
ChildValue table 没有插入任何记录,尽管我提供了值 .
我发现某处 inverse 必须为真,即使它不起作用。
[更新:插入代码]
创建方法
public IList<Parent> Create(IList<Parent> entities)
{
using (ISession session = SessionFactory.OpenSession())
{
foreach (var entity in entities)
{
session.Save(entity);
}
return entities;
}
}
ISessionFactory使用Unity注入并配置为
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
这里最重要的是不要使用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 将此设置设为:"The other end will care about persistence..." 没关系,如果有 class,则 <one-to-many>
。但是不行,如果有<element>
Class (映射为one-to-many
)是一级公民,可以关心持久性... string 不能
此代码现在应该对两个表执行 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>
查看这篇文章了解更多详情:
- inverse = “true” example and explanation 来自 Mkyong
Class:
[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>
但是在测试父实体的保存时,它只插入父实体 table。 ChildValue table 没有插入任何记录,尽管我提供了值 .
我发现某处 inverse 必须为真,即使它不起作用。
[更新:插入代码] 创建方法
public IList<Parent> Create(IList<Parent> entities)
{
using (ISession session = SessionFactory.OpenSession())
{
foreach (var entity in entities)
{
session.Save(entity);
}
return entities;
}
}
ISessionFactory使用Unity注入并配置为
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
这里最重要的是不要使用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 将此设置设为:"The other end will care about persistence..." 没关系,如果有 class,则 <one-to-many>
。但是不行,如果有<element>
Class (映射为one-to-many
)是一级公民,可以关心持久性... string 不能
此代码现在应该对两个表执行 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>
查看这篇文章了解更多详情:
- inverse = “true” example and explanation 来自 Mkyong