gpt4 book ai didi

nhibernate - 从数据库读取时,HasMany 关系导致 "Found shared references to a collection"

转载 作者:行者123 更新时间:2023-12-04 21:13:12 25 4
gpt4 key购买 nike

我是 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 有一个选择的鉴别器 (SelectedDiscriminatorId) 并且鉴别器表包含几种可用语言的描述文本。不是特别喜欢 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 的分类时,我会在执行 session.Flush() 语句时收到 HibernateException,提示“附加信息:找到对集合的共享引用:TestProject.Triage.Discriminators”。

知道这里有什么问题以及我如何纠正吗?谢谢。

这是数据库的外观:
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]

最佳答案

一个更健全的对象模型将是

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 认为鉴别器会独立存在。

关于nhibernate - 从数据库读取时,HasMany 关系导致 "Found shared references to a collection",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30163332/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com