我很难为模型设置Fluent NHibernate映射。
我正在建模一个简单的域,其中Forum
有许多Participants
,每个域都有许多Tags
。
每个关系都是单向 一对多组合
因此,我想将NHibernate配置为在我调用{{时删除Tag
和Tag
之间的关联(即,从集合中删除标签)后删除Participant
。 1}}方法
但是,当我使用ResetTags
方法从Tag
的标签集合中删除Participant
时,在提交事务时会遇到以下异常情况
NHibernate.HibernateException HResult = 0x80131500消息= A 不再引用带有cascade =“ all-delete-orphan”的集合 通过拥有实体的实例: LanguageWire.Dialogues.Domain.Dialogue.Participants Source = mscorlib
请让我知道我在这里想念的东西。
这是缩写代码的样子
ResetTags
这是我的映射
public class Forum : AggregateRoot
{
private IList<Participant> _participants = new List<Participant>();
public virtual IReadOnlyCollection<Participant> Participants => new ReadOnlyCollection<Participant>(_participants);
}
public class Participant : IEquatable<Participant>
{
private int _id;
private IList<Tag> _tags = new List<Tag>();
public virtual void ResetTags(params Tag[] tags)
{
if (tags == null) throw new ArgumentNullException(nameof(tags));
_tags.Clear();
foreach (var tag in tags) _tags.Add(tag);
}
}
public class Tag : IEquatable<Tag>
{
private int _id;
private byte _typeId;
private int _entityId;
}
按照惯例,映射是映射到字段(不是映射到属性,因此用新实例替换NHibernate实现集合没有问题)
public class ForumMapping : ClassMap<Forum>
{
public ForumMapping()
{
Id(x => x.Id);
HasMany(x => x.Participants)
.Not.Inverse()
.Cascade.AllDeleteOrphan()
.BatchSize(Default.BatchSize);
}
}
public class ParticipantMapping : ClassMap<Participant>
{
public ParticipantMapping()
{
Id(x => x.Id);
HasMany(x => x.Tags)
.Cascade.AllDeleteOrphan()
.Not.Inverse()
.Not.KeyNullable()
.Not.KeyUpdate()
.BatchSize(Default.BatchSize);
Cache.ReadWrite().Region(nameof(Participant));
}
}
public class TagMapping : ClassMap<Tag>
{
public TagMapping()
{
Id(x => x.Id);
Map(x => x.EntityId)
.Not.Nullable()
.Not.Update();
Map(x => x.TypeId)
.Not.Nullable()
.Not.Update();
}
}
这是我保存数据的方式
public ISessionFactory BootstrapSessionFactory()
{
NHibernateLogger.SetLoggersFactory(new SerilogNHibernateLoggerFactory());
return Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2012.ConnectionString(_dataAccessConfiguration.DatabaseConnectionString))
.Cache(cache => cache.UseSecondLevelCache())
.Mappings(m =>
m.FluentMappings
.AddFromAssemblyOf<PersistenceSetup>()
.Conventions.Add(
DefaultAccess.CamelCaseField(CamelCasePrefix.Underscore),
我使用的软件包的版本:
_session.FlushMode = FlushMode.Commit;
using (var transaction = _session.BeginTransaction())
{
foreach (var aggregate in _aggregates)
await _session.SaveOrUpdateAsync(aggregate, cancellationToken);
await transaction.CommitAsync(cancellationToken);
}