我是NHibernate的新手,遇到映射问题。我没有谷歌回答。
我的实体看起来像这样:
public class Triage
{
public virtual Guid Id { get; set; }
public virtual IDictionary<int, Discriminator> Discriminators { get; set; }
// This is to keep FluentNHibernate happy
public virtual int? SelectedDiscriminatorId { get; set; }
}
public class Discriminator
{
public virtual int Id { get; set; }
public virtual int LanguageId { get; set; }
public override bool Equals(object obj)
{
var other = obj as Discriminator;
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Id == other.Id && LanguageId == other.LanguageId;
}
public override int GetHashCode()
{
return new { Id, LanguageId }.GetHashCode();
}
}
我的映射看起来像这样:
public class TriageMap : ClassMap<Triage>
{
public TriageMap()
{
Id(x => x.Id).GeneratedBy.GuidComb();
HasMany(x => x.Discriminators)
.KeyColumn("Id")
.PropertyRef("SelectedDiscriminatorId")
.Inverse()
.Cascade.All()
.Not.LazyLoad()
.AsMap(x => x.LanguageId);
// This mapping is only needed to keep FluentNHibernate happy...
Map(x => x.SelectedDiscriminatorId);
}
}
public class DiscriminatorMap : ClassMap<Discriminator>
{
public DiscriminatorMap()
{
CompositeId()
.KeyProperty(x => x.Id)
.KeyProperty(x => x.LanguageId);
}
}
想法是Triage有一个选择的Discriminator(SelectedDiscriminatorId),Discriminator-table包含几种可用语言的描述文本。并不特别喜欢Triage所指的Discriminator与SelectedDiscriminatorId的结构,它只是Discriminator(Id和LanguageId)中复合键的一部分,但这就是我的数据库的外观。
所以,当我像这样取得我的分数时:
_sessionFactory = CreateSessionFactory();
ISession session = _sessionFactory.OpenSession();
CurrentSessionContext.Bind(session);
var triages = _sessionFactory
.GetCurrentSession()
.Query<Triage>()
.Fetch(t => t.Discriminators)
.ToList();
session.Flush();
session.Close();
CurrentSessionContext.Unbind(_sessionFactory);
然后一切正常,条件是SelectedDiscriminatorId在获取的分类中是唯一的。但是,当有几个具有相同SelectedDiscriminatorId的分类时,我得到一个HibernateException说&#34;附加信息:找到对集合的共享引用:TestProject.Triage.Discriminators&#34;当它执行session.Flush()语句时。
知道这里有什么问题以及我如何纠正错误?感谢。
这是数据库的外观:
CREATE TABLE [dbo].[Triage](
[Id] [uniqueidentifier] NOT NULL CONSTRAINT [DF_Triage_Id] DEFAULT (newid()),
[SelectedDiscriminatorId] [int] NULL,
CONSTRAINT [PK_Triage] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[Discriminator](
[ID] [int] NOT NULL,
[DisplayText] [nvarchar](255) NULL,
[LanguageID] [int] NOT NULL,
[Description] [nvarchar](4000) NULL,
CONSTRAINT [PK_Discriminator] 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]
答案 0 :(得分:2)
一个更健全的对象模型将是
public class Triage
{
public virtual Guid Id { get; set; }
public virtual Discriminator SelectedDiscriminator { get; set; }
// left out Equals and GetHashcode
}
public class Discriminator
{
public Discriminator()
{
LocalizedTexts = new Dictionary<int, string>();
}
public virtual int Id { get; set; }
public virtual string Name
{
get
{
switch (Id)
{
case 1:
return "Discriminator A";
case 2:
return "Discriminator B";
case 3:
return "Discriminator C";
default:
return "Unknown";
}
}
}
public virtual IDictionary<int, LocalizedText> LocalizedTexts { get; protected set; }
public override bool Equals(object obj)
{
var other = obj as Discriminator;
return other != null && (Id == 0 ? ReferenceEquals(this, other) : Id == other.Id);
}
public override int GetHashCode()
{
return Id;
}
}
public class LocalizedText
{
public string DisplayName { get; set; }
public string Description { get; set; }
}
带映射
public class TriageMap : ClassMap<Triage>
{
public TriageMap()
{
Id(x => x.Id).GeneratedBy.GuidComb();
References(x => x.SelectedDiscriminator, "SelectedDiscriminatorId");
}
}
public class DiscriminatorMap : ClassMap<Discriminator>
{
public DiscriminatorMap()
{
ReadOnly();
SchemaExport.None(); // do not create Table for this. usefull for creating Schema for in memory unit-testing
Table("Discriminators");
Where("LanguageId = <some value all discriminators have>");
Id(x => x.Id).GeneratedBy.Assigned();
HasMany(x => x.LocalizedTexts)
.Table("Discriminators")
.KeyColumn("Id")
.AsMap("LanguageId")
.Component(c =>
{
c.Map(x => x.DisplayName);
c.Map(x => x.Description);
})
.Cascade.AllDeleteOrphan()
.Not.LazyLoad();
}
}
唯一的缺点是sql看起来有点奇怪,因为NHibernate认为鉴别器本身就存在。