我正在尝试使用NHibernate 3.3.3将我的FluentNHibernate映射转换为NHibernate Mapping By-code。目标是升级到NHibernate 3.3.3并减少分发的程序集数量。我将FluentNHibernate的References映射转换为多对一映射时遇到了一些麻烦。
我的许多实体都有需要翻译的说明。为此,我使用包含所有可用语言的这些文本的文本表。我使用文本ID引用文本表,然后在数据访问对象中我过滤所需的语言。这可以使用NHibernate 3.1和FluentNHibernate创建,使用NHibernate 3.3.3和按代码映射但是我只是一个MappingException说:属性映射列数错误:Category.Description类型:Text。
我的新映射在哪里错了?或者这种类型的映射在NHibernate 3.3.3中是不可能的。
这是文本表(SQL-server 2008)。
CREATE TABLE Texts (
ID int NOT NULL,
languageID nvarchar(10) NOT NULL,
Singular nvarchar(max) NOT NULL,
Plural nvarchar(max) NULL,
CONSTRAINT PK_Texts PRIMARY KEY CLUSTERED (ID ASC, languageID ASC)
WITH (PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
Text类:
public class Text
{
public Text(int id, string language, string singular, string plural)
{
this.ID = new TextCompositeID(id, language);
this.Singular = singular;
this.Plural = plural;
}
public TextCompositeID ID { get; private set; }
public string Plural { get; private set; }
public string Singular { get; set; }
public override bool Equals(object obj)
{
var text = (Text)obj;
if (text == null)
{
return false;
}
return this.ID.Equals(text.ID);
}
public override int GetHashCode()
{
return this.ID.GetHashCode();
}
}
这里的例子是Category类:
public class Category
{
public int ID { get; set; }
public Text Description { get; set; }
}
Category类的FluentNHibernate xml映射如下所示:
<class xmlns="urn:nhibernate-mapping-2.2"
mutable="true"
name="Category"
lazy="false"
table="Category"
where="IsObsolete=0">
<id name="ID" type="System.Int32">
<column name="ID" not-null="true" />
<generator class="native" />
</id>
<many-to-one cascade="none"
class="Text"
name="Description">
<column name="TextID"
not-null="true"
unique="false" />
</many-to-one>
</class>
由此产生:
public class CategoryMap : ClassMap<Category>
{
public CategoryMap()
{
this.Table("Category");
Not.LazyLoad();
this.Where("IsObsolete=0");
Id(x => x.ID)
.Column("ID")
.GeneratedBy.Native()
.Not.Nullable();
References(x => x.Description)
.Column("DescriptionID")
.Cascade.None()
.Not.Unique()
.Not.Nullable();
}
}
这是我创建的NHibernate ClassMapping:
public CategoryMap()
{
this.Lazy(false);
this.Mutable(true);
this.Table("Category");
this.Where("IsObsolete=0");
this.Id(
x => x.ID,
map =>
{
map.Column("ID");
map.Generator(Generators.Native);
});
this.ManyToOne(
x => x.Description,
map =>
{
map.Cascade(Cascade.None);
map.Class(typeof(Text));
map.Column("TextID");
map.Fetch(FetchKind.Join);
map.Lazy(LazyRelation.NoLazy);
map.ForeignKey("none");
});
}
从这里我得到这个xml映射:
<class name="Category"
lazy="false"
table="Category"
where="IsObsolete=0">
<id name="ID"
column="ID"
type="Int32">
<generator class="native" />
</id>
<many-to-one name="Description"
class="Text"
column="TextID"
fetch="join"
foreign-key="none"
lazy="false" />
</class>
答案 0 :(得分:2)
我自己找到了答案。我不得不从Text类中删除复合ID:
public class Text
{
public Text(int id, string language, string singular, string plural)
{
this.ID = id;
this.LanguageID = language;
this.Singular = singular;
this.Plural = plural;
}
public int ID { get; private set; }
public string LanguageID { get; private set; }
public string Plural { get; private set; }
public string Singular { get; set; }
public override bool Equals(object obj)
{
var text = (Text)obj;
if (text == null)
{
return false;
}
return this.ID.Equals(text.ID);
}
public override int GetHashCode()
{
return this.ID.GetHashCode();
}
}
类别映射已成为:
public CategoryMap()
{
this.Lazy(false);
this.Mutable(true);
this.Table("Category");
this.Where("IsObsolete=0");
this.Id(
x => x.ID,
map =>
{
map.Column("ID");
map.Generator(Generators.Native);
});
this.ManyToOne(
x => x.Description,
map =>
{
map.Column("TextID");
map.Fetch(FetchKind.Join);
map.ForeignKey("none");
map.Lazy(LazyRelation.NoLazy);
});
}
在数据访问对象中,旧的QueryOver查询现在可以获得所需的结果。