我正在使用 Castle ActiveRecord 3.0,并且在从数据库中获取对象引用时遇到了问题。当我在同一个 SessionScope 中获取多个实体时,我会为相关实体获得相同的对象引用。
但通常我不能使用相同的会话范围来获取我需要的所有对象。很难描述,所以举个例子:
[ActiveRecord(Table = "car")]
public class Car : ActiveRecordLinqBase<Car>
{
[PrimaryKey("id")]
public virtual int Id { get; set; }
[OneToOne(PropertyRef = "Car", Cascade = CascadeEnum.SaveUpdate)]
public virtual Location Location { get; set; }
}
[ActiveRecord("location")]
public class Location : ActiveRecordLinqBase<Location>
{
[PrimaryKey(Column = "id")]
public virtual int Id { get; set; }
[BelongsTo("car_id", NotFoundBehaviour = NotFoundBehaviour.Ignore,
Cascade = CascadeEnum.SaveUpdate)]
public virtual Car Car { get; set; }
}
[ActiveRecord(Table = "move_order")]
public class MoveOrder : ActiveRecordLinqBase<MoveOrder>
{
[PrimaryKey(Column = "id")]
public virtual int Id { get; set; }
[BelongsTo(Column = "car_id")]
public virtual Car Car { get; set; }
[BelongsTo(Column = "destination_id")]
public virtual Location Destination { get; set; }
}
我正在创建一些对象开始:
using (new SessionScope())
{
var car = new Car() { };
var initialLocation = new Location() { Car = car };
initialLocation.Save();
var destinationLocation = new Location();
destinationLocation.Save();
}
然后,如果我为同一个汽车/位置创建 2 个移动订单,它就可以正常工作:
MoveOrder moveOrder;
MoveOrder moveOrder2;
using (new SessionScope())
{
moveOrder = new MoveOrder()
{
Destination = Location.Queryable.First(x => x.Car == null),
Car = Car.Queryable.First();
};
moveOrder2 = new MoveOrder()
{
Destination = Location.Queryable.First(x => x.Car == null),
Car = Car.Queryable.First()
};
}
对象引用对于:
- moveOrder.Car, moveOrder2.Car
- moveOrder.Location,moveOrder2.Location
但是当我使用不同的会话范围来获取两个 MoveOrders 时:
using (new SessionScope())
{
moveOrder = new MoveOrder()
{
Destination = Location.Queryable.First(x => x.Car == null),
Car = Car.Queryable.First()
};
}
和
using (new SessionScope())
{
moveOrder2 = new MoveOrder()
{
Destination = Location.Queryable.First(x => x.Car == null),
Car = Car.Queryable.First()
};
}
这些属性都不是引用相等的,但从逻辑上讲,它们是相同的实体。我还尝试获取 Nhibernate 会话并将所有分离的对象关联回新会话:
using (var sess = GetSession())
{
sess.Lock(moveOrder.Destination, LockMode.Read);
sess.Lock(moveOrder.Car, LockMode.Read);
moveOrder2 = new MoveOrder()
{
Destination = sess.Get<Location>(moveOrder.Destination.Id),
Car = sess.Get<Car>(moveOrder.Car.Id),
};
}
在这种情况下,这可以解决问题,但有一些问题:
- 我必须将我当前使用的每个数据库实体传递给新会话
- 我不能使用查询,session.Get 适用于 Id
主要问题是:
每次获取相同的实体(相同的 ID)时,如何从数据库中获取相同的对象引用?
还尝试通过在 AR 初始化中配置 Nhibernate 二级缓存并将其添加Cache = CacheEnum.ReadWrite
到每个 db 类 ActiveRecord 属性 - 没有结果。
我宁愿不要一直打开同一个会话。