S#arp Architecture Repository.DbContext.CommitTransaction()不寻常的行为
我面临着一个不寻常的行为,存储库和事务 ,它让我发疯。S#arp Architecture Repository.DbContext.CommitTransaction()不寻常的行为
我有两个简单的POCO类Action和Version,如下所示。从Action-> Version中有 一对多的关系。
public class Action : Entity
{
public virtual string Name
{
get;
set;
}
public virtual IList<Version> Versions
{
get;
protected set;
}
public Action()
{
Versions = new List<Version>();
}
public virtual void AddVersion(Version version)
{
version.Action = this;
Versions.Add(version);
}
}
public class Version : Entity
{
public virtual int Number
{
get;
set;
}
public virtual Action Action
{
get;
set;
}
public Version()
{
}
}
现在我有一个代码段如下:
var actionRep = new Repository<Action>();
var versionRep = new Repository<Version>();
var act1 = new Action();
actionRep .SaveOrUpdate(act1);
using (versionRep .DbContext.BeginTransaction())
{
var v1 = new Version();
act1.AddVersion(v1);
//versionRep .SaveOrUpdate(v1);
versionRep .DbContext.CommitTransaction();
}
在上面的代码,我只是在创建动作和版本库。 首先我使用Action Repository持久化一个Action对象。然后我开始使用版本存储库开始 事务,创建新版本,设置 引用与操作,并提交实际调用版本存储库的 事务。
结果有点奇怪。虽然我尚未在版本存储库上调用SaveOrUpdate方法,但版本对象仍然保留,即使是 也是如此。如果 我注释掉act1.AddVersion(v1);在交易中, ,那么版本不会持续。
后一点斗争的我测试使用NHibernate ,而不是直接使用利用相同 流利映射/配置 夏普架构库相同的情况下(AutoPersistenceModelGenerator.Generate())。结果如预期的 。版本对象不会持久。这里是代码
var sessionFactory = CreateSessionFactory();
_act1 = new Action();
using(var session = sessionFactory.OpenSession())
{
session.SaveOrUpdate(_act1);
}
using(var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
_v1 = new Version();
_act1.AddVersion(_v1);
//session.SaveOrUpdate(_act1);
transaction.Commit();
}
}
CreateSessionFactory()方法如下。如果sombody可以请让我知道为什么我有这个 行为没有什么复杂的
private const string _dbFilename = "nhib_auditing.db";
private static ISessionFactory CreateSessionFactory()
{
return Fluently.Configure()
.Database(SQLiteConfiguration.Standard
.UsingFile(_dbFilename)
.ShowSql())
.Mappings(m => m.AutoMappings.Add(new
AutoPersistenceModelGenerator().Generate()))
.ExposeConfiguration(BuildSchema)
.BuildSessionFactory();
}
现在。它让我发疯。
只是为了让你知道我还没有重写Action和 版本的映射。
等待 纳比尔
这是预期的行为,如果你已经在级联的映射申报操作。当您在act1上调用SaveOrUpdate
时,您使瞬态对象保持不变;也就是说,NHibernate正在跟踪它,并在会话刷新时保存它。使对象持久化的另一种方法是将其与持久对象关联起来,就像您在拨打act1.AddVersion(v1);
时所做的那样。交易提交时,会话被刷新以保存v1。 This article解释了使用持久对象的细节。
顺便说一句,这里是我的两个测试一个与SharpRepositories这是 失败,与NHibernate直接被传递疗法。
[TestFixture]
public class RepositoryTests : RepositoryTestsBase
{
protected override void LoadTestData()
{
}
[Test]
public void TestUsingSharpRespositories
{
var aRep = new Repository<Action>();
var vRep = new Repository<Version>();
_act1 = new Action();
aRep.SaveOrUpdate(_act1);
using(vRep.DbContext.BeginTransaction())
{
_v1 = new Version();
_act1.AddVersion(_v1);
//vRep.SaveOrUpdate(_v1);
vRep.DbContext.CommitTransaction();
}
_v1.IsTransient().ShouldBeTrue();
}
[Test]
public void TestUsingNHibernateSession
{
var sessionFactory = CreateSessionFactory();
_act1 = new Action();
using(var session = sessionFactory.OpenSession())
{
session.SaveOrUpdate(_act1);
}
using(var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
_v1 = new Version();
_act1.AddVersion(_v1);
transaction.Commit();
}
}
_v1.IsTransient().ShouldBeTrue();
}
private const string _dbFilename = "nhib_db.db";
private static ISessionFactory CreateSessionFactory()
{
return Fluently.Configure()
.Database(SQLiteConfiguration.Standard
.UsingFile(_dbFilename)
.ShowSql())
.Mappings(m => m.AutoMappings.Add(new
AutoPersistenceModelGenerator().Generate()))
.ExposeConfiguration(BuildSchema)
.BuildSessionFactory();
}
private static void BuildSchema(Configuration config)
{
if(File.Exists(_dbFilename))
File.Delete(_dbFilename);
new SchemaExport(config).Create(false, true);
}
}
我是新来的流利NHibernate,我从来没有直接使用NHibernate的XML映射。
就映射而言,我使用的是在Visual Studio中创建新的Sharp Architecture项目时设置的vanilla automapping配置。我有一个的hasMany约定如下:
public class HasManyConvention : IHasManyConvention
{
public void
Apply(FluentNHibernate.Conventions.Instances.IOneToManyCollectionInstance
instance)
{
instance.Key.Column(instance.EntityType.Name + "Fk");
instance.Inverse();
instance.Cascade.All();
}
}
我更新了我的TestUsingNHibernateSession如下测试,以测试它的行为,如果我在一个会议上操纵动作都和版本。并猜测Version对象被保存的是什么,即使事务的开始和提交之间没有任何内容。
[Test]
public void TestUsingNHibernateSession
{
var sessionFactory = CreateSessionFactory();
_act1 = new Action();
using(var session = sessionFactory.OpenSession())
{
session.SaveOrUpdate(_act1);
//}
//using(var session = sessionFactory.OpenSession())
//{
_v1 = new Version();
_act1.AddVersion(_v1);
using (var transaction = session.BeginTransaction())
{
transaction.Commit();
}
}
_v1.IsTransient().ShouldBeTrue();
}
所以我的结论是,它的一切都与会议。如果在会话中创建或检索到对象A,并且稍后如果在该会话内开始新的事务,则在该事务提交后,与对象A相关联的所有瞬态或脏对象也被保存,否在Begin和Commit之内或之外创建其他对象。
任何人都可以让我知道他们是否同意我的理解?我还假设夏普架构通过每个Web请求使用单个nhibernate Session?
等待 纳比尔
您应该编辑您的问题以包含此内容,而不是将其作为回答发布 – 2010-06-22 22:08:44
对不起,艾萨克。实际上,我最初将它发布在S#arp架构谷歌邮件列表中,并且我从那里粘贴了一个副本 – nabeelfarid 2010-06-23 10:37:11
tl; dr。你能用更少的话来缩小它的范围吗? – 2010-06-22 22:39:58
对不起,毛里西奥。我实际上发布它在S#arp架构谷歌邮件列表,并且我有点从那里复制。 – nabeelfarid 2010-06-23 10:36:13