我正在尝试在流利的 NHibernate 中进行简单的一对多映射,但是我收到以下异常:
“NHibernate.TransientObjectException:对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例或将属性的级联操作设置为使其自动保存的内容。类型:Voter.Domain.Entities.VoteOption,实体:Voter.Domain.Entities .VoteOption"
我已经尝试过无数次使用 Cascade().All() - 但这没有区别。
请帮助我让这个级联工作!已经浪费了很多时间...
我有以下实体:
public class Vote
{
public Vote()
{
VoteOptions = new List<VoteOption>();
}
public virtual int Id { get; protected set; }
public virtual Guid VoteReference { get; set; }
public virtual string Title { get; set; }
public virtual string Description { get; set; }
public virtual DateTime ValidFrom { get; set; }
public virtual DateTime ValidTo { get; set; }
public virtual IList<VoteOption> VoteOptions { get; set; }
public virtual void AddOption(VoteOption voteOption)
{
VoteOptions.Add(voteOption);
}
public virtual void AddOptions(List<VoteOption> options)
{
foreach (var option in options.Where(option => VoteOptionAlreadyExists(option) == false))
{
VoteOptions.Add(option);
}
}
private bool VoteOptionAlreadyExists(VoteOption voteOption)
{
return VoteOptions.Any(x => x.Description == voteOption.Description);
}
}
public class VoteOption
{
public virtual int Id { get; protected set; }
public virtual string LongDescription { get; set; }
public virtual string Description { get; set; }
public virtual Vote Vote { get; set; }
}
以及以下映射:
public VoteMap()
{
Table("Vote");
Id(x => x.Id).GeneratedBy.Identity().Column("Id");
Map(x => x.VoteReference).Column("VoteReference");
Map(x => x.Title).Column("Title").Not.Nullable();
Map(x => x.Description).Column("Description").Not.Nullable();
Map(x => x.ValidFrom).Column("ValidFrom").Not.Nullable();
Map(x => x.ValidTo).Column("ValidTo").Not.Nullable();
HasMany(x => x.VoteOptions).KeyColumn("Vote_Id").Cascade.All();
}
public class VoteOptionMap : ClassMap<VoteOption>
{
public VoteOptionMap()
{
Table("VoteOption");
Id(x => x.Id).GeneratedBy.Identity().Column("Id");
Map(x => x.Description).Column("Description").Not.Nullable();
Map(x => x.LongDescription).Column("LongDescription").Not.Nullable();
References(x => x.Vote).Column("Vote_Id").Cascade.All();
}
}
以及以下 SQL Server 数据库表:
CREATE TABLE dbo.Vote
(
Id INT IDENTITY(1,1) PRIMARY KEY,
VoteReference UNIQUEIDENTIFIER NULL,
Title VARCHAR(500) NOT NULL,
[Description] VARCHAR(1000) NOT NULL,
ValidFrom DATETIME NOT NULL,
ValidTo DATETIME NOT NULL
)
CREATE TABLE dbo.VoteOption
(
Id INT IDENTITY(1,1) PRIMARY KEY,
Vote_Id INT NOT NULL,
[Description] VARCHAR(500) NOT NULL,
LongDescription VARCHAR(5000) NOT NULL
)
实现代码为:
public void Save()
{
var vote = new Vote
{
VoteReference = new Guid(),
Title = "Events Vote",
Description = "Which event would you like to see next?",
ValidFrom = DateTime.Now.AddDays(-2),
ValidTo = DateTime.Now.AddDays(3)
};
var options = new List<VoteOption>
{
new VoteOption {Description = "What you want?", LongDescription = "Tell me all about it..."},
new VoteOption {Description = "Another option?", LongDescription = "Tell me some more..."}
};
vote.AddOptions(options);
using (var session = sessionFactory().OpenSession())
{
using (var transaction = session.BeginTransaction())
{
//This works - but undermines cascade!
//foreach (var voteOption in vote.VoteOptions)
//{
// session.Save(voteOption);
//}
session.Save(vote);
transaction.Commit();
}
}
}
private ISessionFactory sessionFactory()
{
var config = new Configuration().Configure();
return Fluently.Configure(config)
.Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<Vote>()))
.BuildSessionFactory();
}