nhibernate - NHibernate 在查询中使用错误的键,抛出 ObjectNotFoundByUniqueKeyException
问题描述
ObjectNotFoundByUniqueKeyException
使用 NHibernate 5.2,当我执行以下操作时,由于使用无效键执行错误查询,我得到了一个:
var session = sessionFactory.OpenSession();
var employee = new Employee(){
UserId = "joe",
Certifications = new List<Certification>()
};
employee.Certifications.Add(new Certification() { Employee = employee});
var id = session.Save(employee);
session.Flush();
session.Clear();
var emp = session.Get<Employee>(id);
foreach(var e in emp.Certifications)
{
Console.WriteLine(e.Id);
}
执行的查询
NHibernate: INSERT INTO Employee (UserId) VALUES (@p0); select SCOPE_IDENTITY();@p0 = 'joe' [Type: String (4000:0:0)]
NHibernate: INSERT INTO Certification (UserId) VALUES (@p0); select SCOPE_IDENTITY();@p0 = 'joe' [Type: String (4000:0:0)]
NHibernate: SELECT userquery_0_.Id as id1_0_0_, userquery_0_.UserId as userid2_0_0_ FROM Employee userquery_0_ WHERE userquery_0_.Id=@p0;@p0 = 1 [Type: Int32 (0:0:0)]
NHibernate: SELECT certificat0_.UserId as userid2_1_1_, certificat0_.Id as id1_1_1_, certificat0_.Id as id1_1_0_, certificat0_.UserId as userid2_1_0_ FROM Certification certificat0_ WHERE certificat0_.UserId=@p0;@p0 = 1 [Type: Int32 (0:0:0)]
NHibernate: SELECT userquery_0_.Id as id1_0_0_, userquery_0_.UserId as userid2_0_0_ FROM Employee userquery_0_ WHERE userquery_0_.UserId=@p0;@p0 = '1' [Type: String (4000:0:0)]
我期待@p0 = 'joe'
在最后两个查询中,而不是1
and '1'
。任何人都可以看到下面可以解释这种行为的映射问题吗?
类/映射
public class Employee
{
public virtual int Id { get; set; }
public virtual string UserId { get; set; }
public virtual ICollection<Certification> Certifications { get; set; }
}
public class EmployeeMap : ClassMap<Employee>
{
public EmployeeMap()
{
Table("Employee");
Id(x => x.Id);
Map(x => x.UserId);
HasMany(x => x.Certifications)
.KeyColumn("UserId")
.Cascade.All();
}
}
public class Certification
{
public virtual int Id { get; set; }
public virtual Employee Employee { get; set; }
}
public class CertificationMap : ClassMap<Certification>
{
public CertificationMap()
{
Table("Certification");
Id(x => x.Id);
References(x => x.Employee)
.Column("UserId")
.PropertyRef(x => x.UserId);
}
}
解决方案
Collection没有使用 Employee 的主键,而是另一个属性 - PropertyRef
。我们必须像多对一一样通知一对多映射
HasMany(x => x.Certifications)
.KeyColumn("UserId")
.Cascade.All()
// use property, not the ID, when searching for my items
.PropertyRef("UserId")
;
缺少此映射的事实导致在 NHibernate 加载集合时使用 ID(魔术 1)
推荐阅读
- excel - 在 VBA 中将工作表作为变量引用
- linux - 了解 turbostat 调试模式最大涡轮输出
- r - 如何在 for 循环中将月份添加到日期并将结果附加到列表或数据框?
- python - 优化构造标签功能,使其适合并行处理。我的代码中的 for 循环正在造成瓶颈
- android - 在嵌套滚动视图中如何滚动 pdf 视图
- visual-studio-2019 - 如何在 Visual Studio 中向 Properties.Settings.Default 添加可编辑属性?
- javascript - 是否可以从 HTA 的 IE11 WSShell 中的 WMIC 直接输出?
- pine-script - 要记录的当天第一根蜡烛的高点和低点
- reactjs - 用户停止输入时的搜索仅在第一次有效(React)
- java - 安卓 | 可以在列表中创建一个点彩球吗?