如果关联的列名相同,则在构建 SessionFactory 时出现 NHibernate 异常 属性
NHibernate Exception while building SessionFactory if column name is same for association property
我有主表和明细表。两个表中的主键列名称相同:Id
.
在构建会话工厂时,出现以下异常:
NHibernate.MappingException: Unable to build the insert statement for class ........Detail1Entity: a failure occured when adding the Id of the class ---> System.ArgumentException: The column 'Id' has already been added in this SQL builder
Parameter name: columnName
at NHibernate.SqlCommand.SqlInsertBuilder.AddColumnWithValueOrType(String columnName, Object valueOrType)
at NHibernate.SqlCommand.SqlInsertBuilder.AddColumns(String[] columnNames, Boolean[] insertable, IType propertyType)
at NHibernate.Persister.Entity.AbstractEntityPersister.GenerateInsertString(Boolean identityInsert, Boolean[] includeProperty, Int32 j)
--- End of inner exception stack trace ---
at NHibernate.Persister.Entity.AbstractEntityPersister.GenerateInsertString(Boolean identityInsert, Boolean[] includeProperty, Int32 j)
at NHibernate.Persister.Entity.AbstractEntityPersister.GenerateInsertString(Boolean[] includeProperty, Int32 j)
at NHibernate.Persister.Entity.AbstractEntityPersister.PostInstantiate()
at NHibernate.Persister.Entity.SingleTableEntityPersister.PostInstantiate()
at NHibernate.Impl.SessionFactoryImpl..ctor(Configuration cfg, IMapping mapping, Settings settings, EventListeners listeners)
at NHibernate.Cfg.Configuration.BuildSessionFactory()
at ...........
我有以下表格:
CREATE Table MasterTable1
(
[Id] [INT] IDENTITY (1,1) NOT NULL CONSTRAINT MasterTable1PK PRIMARY KEY,
[MasterData] [VARCHAR] (100)
)
CREATE Table DetailTable1
(
[Id] [INT] IDENTITY (1,1) NOT NULL CONSTRAINT DetailTable1PK PRIMARY KEY,
[MasterId] [INT] NOT NULL CONSTRAINT DetailTable1_MasterTable1_FK FOREIGN KEY REFERENCES MasterTable(MasterId),
[DetailData] [VARCHAR] (100)
)
以下是实体定义:
public class Master1Entity
{
public virtual int Id { get; set; }
public virtual string MasterData { get; set; }
}
public class Detail1Entity
{
public virtual int Id { get; set; }
public virtual string DetailData { get; set; }
public virtual Master1Entity Master1 { get; set; }
}
以下是映射:
internal class Master1Map : ClassMapping<Master1Entity>
{
public Master1Map()
{
Table("MasterTable1");
Id(x => x.Id, im =>
{
im.Column("Id");
im.Generator(Generators.Identity);
});
Property(x => x.MasterData);
}
}
internal class Detail1Map : ClassMapping<Detail1Entity>
{
public Detail1Map()
{
Table("DetailTable1");
Id(x => x.Id, im =>
{
im.Column("Id");
im.Generator(Generators.Identity);
});
Property(x => x.DetailData);
ManyToOne(x => x.Master1, map => { map.Column("Id"); });
}
}
如 所述,我知道如果我将 [MasterTable1].[Id]
重命名为 [MasterTable1].[MasterId]
并相应地修改实体和映射,这会很好。
但是,我无法更改底层数据库;这是我必须处理的遗留数据库。
此外,这是多对一关系。一个 Master 将有多个 Detail 条目。
有什么方法可以在不更改数据库中的列名的情况下完成这项工作吗?
不要混淆集合映射(期望来自关联 table 的列)与实体映射(期望来自所有者 table 的列)。 ManyToOne
是实体映射,它需要来自 owner table 的列。在您的情况下,Master1
的所有者 table 是 DetailTable1
,您需要映射的列是 MasterId
:
internal class Detail1Map : ClassMapping<Detail1Entity>
{
...
ManyToOne(x => x.Master1, map => { map.Column("MasterId"); });
我有主表和明细表。两个表中的主键列名称相同:Id
.
在构建会话工厂时,出现以下异常:
NHibernate.MappingException: Unable to build the insert statement for class ........Detail1Entity: a failure occured when adding the Id of the class ---> System.ArgumentException: The column 'Id' has already been added in this SQL builder
Parameter name: columnName
at NHibernate.SqlCommand.SqlInsertBuilder.AddColumnWithValueOrType(String columnName, Object valueOrType)
at NHibernate.SqlCommand.SqlInsertBuilder.AddColumns(String[] columnNames, Boolean[] insertable, IType propertyType)
at NHibernate.Persister.Entity.AbstractEntityPersister.GenerateInsertString(Boolean identityInsert, Boolean[] includeProperty, Int32 j)
--- End of inner exception stack trace ---
at NHibernate.Persister.Entity.AbstractEntityPersister.GenerateInsertString(Boolean identityInsert, Boolean[] includeProperty, Int32 j)
at NHibernate.Persister.Entity.AbstractEntityPersister.GenerateInsertString(Boolean[] includeProperty, Int32 j)
at NHibernate.Persister.Entity.AbstractEntityPersister.PostInstantiate()
at NHibernate.Persister.Entity.SingleTableEntityPersister.PostInstantiate()
at NHibernate.Impl.SessionFactoryImpl..ctor(Configuration cfg, IMapping mapping, Settings settings, EventListeners listeners)
at NHibernate.Cfg.Configuration.BuildSessionFactory()
at ...........
我有以下表格:
CREATE Table MasterTable1
(
[Id] [INT] IDENTITY (1,1) NOT NULL CONSTRAINT MasterTable1PK PRIMARY KEY,
[MasterData] [VARCHAR] (100)
)
CREATE Table DetailTable1
(
[Id] [INT] IDENTITY (1,1) NOT NULL CONSTRAINT DetailTable1PK PRIMARY KEY,
[MasterId] [INT] NOT NULL CONSTRAINT DetailTable1_MasterTable1_FK FOREIGN KEY REFERENCES MasterTable(MasterId),
[DetailData] [VARCHAR] (100)
)
以下是实体定义:
public class Master1Entity
{
public virtual int Id { get; set; }
public virtual string MasterData { get; set; }
}
public class Detail1Entity
{
public virtual int Id { get; set; }
public virtual string DetailData { get; set; }
public virtual Master1Entity Master1 { get; set; }
}
以下是映射:
internal class Master1Map : ClassMapping<Master1Entity>
{
public Master1Map()
{
Table("MasterTable1");
Id(x => x.Id, im =>
{
im.Column("Id");
im.Generator(Generators.Identity);
});
Property(x => x.MasterData);
}
}
internal class Detail1Map : ClassMapping<Detail1Entity>
{
public Detail1Map()
{
Table("DetailTable1");
Id(x => x.Id, im =>
{
im.Column("Id");
im.Generator(Generators.Identity);
});
Property(x => x.DetailData);
ManyToOne(x => x.Master1, map => { map.Column("Id"); });
}
}
如 [MasterTable1].[Id]
重命名为 [MasterTable1].[MasterId]
并相应地修改实体和映射,这会很好。
但是,我无法更改底层数据库;这是我必须处理的遗留数据库。
此外,这是多对一关系。一个 Master 将有多个 Detail 条目。
有什么方法可以在不更改数据库中的列名的情况下完成这项工作吗?
不要混淆集合映射(期望来自关联 table 的列)与实体映射(期望来自所有者 table 的列)。 ManyToOne
是实体映射,它需要来自 owner table 的列。在您的情况下,Master1
的所有者 table 是 DetailTable1
,您需要映射的列是 MasterId
:
internal class Detail1Map : ClassMapping<Detail1Entity>
{
...
ManyToOne(x => x.Master1, map => { map.Column("MasterId"); });