Nhibernate:在事务中插入新的子数据并持久化父数据

Nhibernate:在事务中插入新的子数据并持久化父数据,nhibernate,transactions,version,Nhibernate,Transactions,Version,我有两个班,作为父母的旅行和作为孩子的机票 public class Trip : Entity { public string TripNo { get; set; } public string IsActive { get; set; } } public class Ticket : Entity { public Trip Trip { get; set; } public string TicketNo { get; set; } } 在事务中,如何确保在

我有两个班,作为父母的旅行和作为孩子的机票

public class Trip : Entity
{
   public string TripNo { get; set; }
   public string IsActive { get; set; }
}

public class Ticket : Entity
{
   public Trip Trip { get; set; }
   public string TicketNo { get; set; }
}
在事务中,如何确保在Trip.IsActive中添加新票证为true,并且在其他事务中未被修改。如果我检查trip的一个版本,它仍然可以在其他事务上修改。如果我(在所选的行程中)锁定,它将有一个性能问题,因为在一秒钟内有数千个票插入。 谢谢您的建议。

//将课堂改为
// change class to 
public class Trip : Entity
{
   public int Version { get; private set; }

   public string TripNo { get; set; }
   public string IsActive { get; set; }
}

// configure using FluentNhibernate Mapping
// in TripMap
Version(t => t.Version);

// use like this
void AddTicket(string tripno, string ticketNo)
{
    bool interupted = false;
    do
    {
        interupted = false;
        try
        {
            using(var tx = session.BeginTransaction())
            {
                var trip = session.Query<Trip>().Where(t => t.TripNo == tripno && t.IsActive).FirstOrDefault();
                if (trip == null)
                    return;
                var ticket = new Ticket { TicketNo = ticketNo, Trip = trip };
                session.SaveOrUpdate(ticket);
                tx.Commit()
            }
        }
        catch(StaleObjectException)
        {
            // someone messed up with the Trip
            interupted = true;
        }
    } while (interupted);
}
公务舱旅行:实体 { 公共int版本{get;private set;} 公共字符串TripNo{get;set;} 公共字符串是活动的{get;set;} } //使用FluentNhibernate映射进行配置 //在TripMap中 版本(t=>t.Version); //像这样使用 void AddTicket(字符串tripno、字符串ticketNo) { 布尔中断=假; 做 { 中断=错误; 尝试 { 使用(var tx=session.BeginTransaction()) { var trip=session.Query(); 如果(行程==null) 返回; var票证=新票证{TicketNo=TicketNo,Trip=Trip}; 会话。保存或更新(票据); tx.Commit() } } 捕获(StaleObjectException) { //有人把旅行搞砸了 中断=真; } }当(被打断); }
更新:为了证明它,请加载System.Data.Sqlite.dll并使用以下代码创建一个新的ConsoleApp

var config = Fluently.Configure()
    .Database(SQLiteConfiguration.Standard.InMemory().ShowSql().FormatSql())
    .Mappings(m => m.FluentMappings
        .Add<TripMap>()
    )
    .BuildConfiguration();

var sf = config.BuildSessionFactory();

using (var session = sf.OpenSession())
using (var session2 = sf.OpenSession(session.Connection))  // use the same connection because inmemory dbs are bound to the connection, nevertheless the session act as if they have different connections
{
    new SchemaExport(config).Execute(true, true, false, session.Connection, null);

    // fill the database
    int tripId = session.Save(new Trip { No = "1" });
    session.Flush();
    session.Clear();  // Clear cache

    var user1 = session.Get<Trip>(tripId);
    var user2 = session2.Get<Trip>(tripId);

    user1.No = 2;
    user2.No = 3;

    session.Flush();
    session2.Flush(); // throws StaleObjectException here
}
var config=fluntly.Configure()
.Database(SQLiteConfiguration.Standard.InMemory().ShowSql().FormatSql())
.Mappings(m=>m.FluentMappings
.Add()
)
.BuildConfiguration();
var sf=config.BuildSessionFactory();
使用(var session=sf.OpenSession())
使用(var session2=sf.OpenSession(session.Connection))//使用相同的连接,因为内存中的数据库绑定到该连接,但是会话的行为就像它们有不同的连接一样
{
新SchemaExport(config.Execute)(true、true、false、session.Connection、null);
//填充数据库
int tripId=session.Save(新Trip{No=“1”});
session.Flush();
session.Clear();//清除缓存
var user1=session.Get(tripId);
var user2=session2.Get(tripId);
user1.No=2;
user2.No=3;
session.Flush();
session2.Flush();//此处抛出StaleObjectException
}

旅行和机票之间的关系是一对多、多对多还是一对一?嗯,我忘了怎么改变旅行了。否则,NHibernate不会对其进行更改。我将在明天回顾您的解决方案,该解决方案显示,如果在事务中间修改trip,NHibernate将抛出StaleObjectException。如何证明呢?