gpt4 book ai didi

c# - 流利的 NHibernate : How do I map Many-to-Many Relationships with additional attributes on the relationship table?

转载 作者:太空狗 更新时间:2023-10-30 01:10:32 25 4
gpt4 key购买 nike

我正在尝试映射两个实体之间的多对多关系,但我需要使用多个属性来装饰该实体 - 请参见下图:

Many-to-Many Relationship with additional attributes on relationship table

Reads 是我在这种情况下的关系表 - 我在上面添加了一个标识列以避免使用复合键,但这里有值(value)的信息实际上是 UserId、FeedItemId 和TimeRead 属性。根据我在 StackOverFlow 上看到的类似示例,以下是我尝试映射这种关系的方式:

用户

public class UserMap : ClassMap<User>
{
public UserMap()
{
Id(x => x.UserId).GeneratedBy.Identity();
Map(x => x.UserName).Length(DataConstants.UserNameLength).Unique().Not.Nullable();
Map(x => x.EmailAddress).Length(DataConstants.EmailAddressLength).Unique().Not.Nullable();
Map(x => x.DateJoined).Not.Nullable();
Map(x => x.Password).Length(DataConstants.PasswordHashLength).Not.Nullable();
HasManyToMany(x => x.UserRoles).Cascade.AllDeleteOrphan().AsBag().Table("UsersInRole");
HasManyToMany(x => x.SubscribedFeeds).Cascade.DeleteOrphan().AsBag().Table("Subscriptions");
HasManyToMany(x => x.OwnedFeeds).Cascade.All().AsBag().Table("FeedOwners");
HasMany(x => x.Reads).Cascade.DeleteOrphan().Fetch.Join().Inverse().KeyColumn("UserId");
}
}

FeedItem

public class FeedItemMap : ClassMap<FeedItem>
{
public FeedItemMap()
{
Id(x => x.FeedItemId).GeneratedBy.Identity();
Map(x => x.OriginalUri).Not.Nullable().Unique().Length(DataConstants.FeedUriLength);
Map(x => x.DatePublished).Not.Nullable();
Map(x => x.Title).Not.Nullable().Length(DataConstants.FeedItemTitleLength);
References(x => x.Feed);
HasManyToMany(x => x.Tags).Cascade.All().Table("PostTags");
HasManyToMany(x => x.Categories).Cascade.All().Table("PostsInCategory");
HasMany(x => x.Reads).Cascade.AllDeleteOrphan().Inverse().Fetch.Join().KeyColumn("FeedItemId");
}
}

阅读:

public class FeedReadMap : ClassMap<FeedRead>
{
public FeedReadMap()
{
Table("Reads");
//CompositeId()
// .KeyProperty(x => x.TimeRead, "TimeRead")
// .KeyReference(x => x.ItemRead, "FeedItemId")
// .KeyReference(x => x.Reader, "UserId");
Id(x => x.ReadId).GeneratedBy.Identity();
Map(x => x.TimeRead).Not.Nullable();
References(x => x.Reader).Not.Nullable().Cascade.SaveUpdate().Column("UserId");
References(x => x.ItemRead).Not.Nullable().Cascade.SaveUpdate().Column("FeedItemId");
}
}

此代码不会按原样引发错误,但当我尝试执行以下操作时,不会将任何内容持久保存到 Reads 表中:

var read = new FeedRead {ItemRead = feed.Items[0], Reader = user, TimeRead = DateTime.Now};
user.Reads.Add(read);
feed.Items[0].Reads.Add(read);

_repository.SaveUser(user);

这可能是因为 User 和 FeedItem 在关系映射上都有一个 .Inverse - 我这样做是因为这是我在大多数其他试图对此建模的示例中看到的相同的关系。

当我从用户映射中删除 .Inverse 时,我得到了这个错误:

NHibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing.

我的最终目标是能够执行 Session.SaveOrUpdate(user) 并将任何新的提要读取直接插入到读取表中,但我还没有找到实现它的方法。我做错了什么?

我几乎已经通读了 StackOverFlow 上关于该主题的所有其他问题,但尚未找到该问题的明确答案。

最佳答案

这完全取决于您希望如何保存新阅读。

如果你想通过 User 保存新的 Reads,那么你需要 Cacascade.AllDeleteOrphan() for User。就目前而言,它不会级联新读取,因为您只有 DeleteOrphan。

public class UserMap : ClassMap<User>
{
public UserMap()
{
Id(x => x.UserId).GeneratedBy.Identity();
Map(x => x.UserName).Length(DataConstants.UserNameLength).Unique().Not.Nullable();
Map(x => x.EmailAddress).Length(DataConstants.EmailAddressLength).Unique().Not.Nullable();
Map(x => x.DateJoined).Not.Nullable();
Map(x => x.Password).Length(DataConstants.PasswordHashLength).Not.Nullable();
HasManyToMany(x => x.UserRoles).Cascade.AllDeleteOrphan().AsBag().Table("UsersInRole");
HasManyToMany(x => x.SubscribedFeeds).Cascade.DeleteOrphan().AsBag().Table("Subscriptions");
HasManyToMany(x => x.OwnedFeeds).Cascade.All().AsBag().Table("FeedOwners");
HasMany(x => x.Reads).Cascade.AllDeleteOrphan().Fetch.Join().Inverse().KeyColumn("UserId");
}
}

只是一个想法,我总是喜欢尽量减少双向关系,以试图让领域更简单。因此,如果可以避免的话,我可能不会在 User 或 FeedItem 上拥有集合。

关于c# - 流利的 NHibernate : How do I map Many-to-Many Relationships with additional attributes on the relationship table?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4516139/

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