流暢な NHibernate で単純な 1 対多のマッピングを実行しようとしていますが、次の例外が発生します。
「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();
}