gpt4 book ai didi

c# - 如何在 NHibernate 中映射多对多对多的三元关系?

转载 作者:行者123 更新时间:2023-11-30 12:42:15 24 4
gpt4 key购买 nike

尝试建立多对多对多关联。

我目前的情况是这样的:

namespace com.example // Assembly = com.example
{

public class Foo
{
public virtual long Id { get; set; }
public virtual IDictionary<string, ISet<PersistentClass>> MappedCollections { get; set; }
}

public class PersistentClass
{
public virtual long Id { get; protected set; }
public virtual string Prop { get; set; }
}
}

这是我的映射:

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">

<class name="com.example.Foo, com.example">
<id name="Id" type="Int64" generator="hilo" />
<map name="MappedCollections">
<key column="Id" />
<index column="Key" type="String" />
<many-to-many class="com.example.PersistentClass, com.example" />
</map>
</class>

<class name="com.example.PersistentClass, com.example">
<id name="Id" type="Int64" generator="hilo" />
<property name="Prop" />
</class>

</hibernate-mapping>

创建模式会生成以下 SQL(SqlServer 示例):

if exists (select 1 from sys.objects where object_id = OBJECT_ID(N'[FKC8D94E45A4783B9]') AND parent_object_id = OBJECT_ID('MappedCollections'))
alter table MappedCollections drop constraint FKC8D94E45A4783B9


if exists (select 1 from sys.objects where object_id = OBJECT_ID(N'[FKC8D94E46534DBE0]') AND parent_object_id = OBJECT_ID('MappedCollections'))
alter table MappedCollections drop constraint FKC8D94E46534DBE0


if exists (select * from dbo.sysobjects where id = object_id(N'Foo') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table Foo

if exists (select * from dbo.sysobjects where id = object_id(N'MappedCollections') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table MappedCollections

if exists (select * from dbo.sysobjects where id = object_id(N'PersistentClass') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table PersistentClass

if exists (select * from dbo.sysobjects where id = object_id(N'hibernate_unique_key') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table hibernate_unique_key

create table Foo (
Id BIGINT not null,
primary key (Id)
)

create table MappedCollections (
Id BIGINT not null,
elt BIGINT not null,
Key NVARCHAR(255) not null,
primary key (Id, Key) -- !! WRONG !! should be unique (Id, elt, Key)
)

create table PersistentClass (
Id BIGINT not null,
Prop NVARCHAR(255) null,
primary key (Id)
)

alter table MappedCollections
add constraint FKC8D94E45A4783B9
foreign key (elt)
references PersistentClass

alter table MappedCollections
add constraint FKC8D94E46534DBE0
foreign key (Id)
references Foo

create table hibernate_unique_key (
next_hi BIGINT
)

insert into hibernate_unique_key values ( 1 )

知道我做错了什么吗?从我们的 SQL 中,我们可以看到它一直保持为 IDictionary<string, PersistentClass>。而不是 IDictionary<string, ISet<PersistentClass> , 我不想要许多 Foo 的多对多关系多对 stringPersistent类,其中每一对都是唯一的 Foo .所有三个 值都应该创建一个唯一值。

我该怎么做?

(注意:我包含了 Hibernate 标签,因为无论是 Hibernate 还是 NHibernate,这种关系的 xml 映射应该是相同的)

最佳答案

虽然它创建了一个不必要的连接,但创建另一个实体可以做到这一点,同时保持非常相似的公共(public)接口(interface)。

基本上:

namespace com.example // Assembly = com.example
{

public class Foo
{
public virtual long Id { get; set; }

public virtual ReadOnlyDictionary<string, ISet<PersistentClass>> MappedCollections
{
get
{
return new ReadOnlyDictionary<string, ISet<PersistentClass>>(_mc);
}
}

protected virtual IDictionary<string, PersistentClassSet> _mc { get; set; }
public virtual void InitializeCollection(string key)
{
if (!_mk.ContainsKey(key))
_mc[key] = new PersistentClassSet();
}
}

public class PersistentClass
{
public virtual long Id { get; protected set; }
public virtual string Prop { get; set; }
}

internal class PersistentClassSet : ISet<PersisitentClass>
{
public PersistentClassSet()
{
Proxy = new HashSet<PersistentClass>();
}

protected virtual long Id { get; set; }
protected virtual ISet<PersistentClass> Proxy { get; set; }

public bool Add(PersistentClass item)
{
return Proxy.Add(item);
}

// other ISet implementations delegated to Proxy
}
}

映射如下:

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">

<class name="com.example.Foo, com.example">
<id name="Id" type="Int64" generator="hilo" />
<map name="MappedCollections">
<key column="Id" />
<index column="Key" type="String" />
<many-to-many class="com.example.PersistentClassSet, com.example" />
</map>
</class>

<class name="com.example.PersistentClass, com.example">
<id name="Id" type="Int64" generator="hilo" />
<property name="Prop" />
</class>

<class name="com.example.PersistentClassSet, com.example">
<id name="Id" type="Int64" generator="hilo" />
<set name="Proxy">
<key column="Id"/>
<many-to-many class="com.example.PersistentClass, com.example" />
</set>
</class>
</hibernate-mapping>

关于c# - 如何在 NHibernate 中映射多对多对多的三元关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34346239/

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