如何更新具有一对一关系的实体



我有如下实体:

public class Device
{
public long Guid { get; set; }
public List<Computer> Computers { get; set; }
public string ShopName { get; set; }
}
public class Computer
{
public long Guid { get; set; }
public long SerialNo { get; set; }
public Device Device { get; set; }
public Condition Condition { get; set; }
}
public class Condition
{
public long Guid { get; set; }
public bool hasDamage { get; set; }
public bool IsSecondHand { get; set; }
public Computer Computer { get; set; }
}

我的服务要求是:

public class Request
{
public long? DeviceGuid {get; set;}
public long? SerialNo {get; set;}
public bool? IsSecondHand {get; set;}
}

我想根据的要求更新所有的电脑

foreach (var requestItem in RequestList)
{
var ComputerPredicate = PredicateBuilder.True<Computer>()
.And(x => x.SerialNo== requestItem.SerialNo)
.And(x => x.Device.Guid== requestItem.DeviceGuid);
var computers = from computers in ISession.Query<Computer>()
.Where(ComputerPredicate)
select computers;
computers.Update(u => new Computer()
{
Condition = new Condition()
{
IsSecondHand = requestItem.IsSecondHand.GetValueOrDefault(false),
} 
});

如果Request.DeviceGuid不为空,我会更新属于该设备的所有计算机;如果CCD_ 2不为空,则我仅更新计算机。在列表的每个项目中,其中一个总是空的。

但我收到一个错误

NHibernate.Exceptions.GenericADOException:'无法执行更新查询[SQL:update COMPUTER set Condition.IsSecondHand=?where and seriano=?]'
PostgresException:42703:column"条件";关系式";"计算机";不存在

SQL中确实没有任何关系。

还有另一个选项,我可以成功更新,但我不确定这是一个有效的方法:

var computerList = computers.ToList();
foreach (var computer in computerList)
{
computer.Condition.IsSecondHand = requestItem.IsSecondHand.GetValueOrDefault(false);
ISession.Save(computer)
}

那么,我该如何以最有效的方式处理这种情况呢?

NHibernate中的LINQ更新不支持对关系实体的更新。您可以尝试使用子查询来查找需要更新的所有实体。类似于:

var entitiesToUpdateSubQuery = session.Query<Computer>()
.Where(ComputerPredicate)
.Select(x => x.Condition); //<- Select entity  you need to update
session.Query<Condition>() //<- Write update query directly on entity you need to update
.Where(c => entitiesToUpdateSubQuery.Contains(c)) 
.Update(c => 
new Condition()
{
IsSecondHand = requestItem.IsSecondHand.GetValueOrDefault(false),
}
);

最新更新