FirstOrDefault returns 外键为空
FirstOrDefault returns null on foreign key
假设我们有以下模型:
public class ReadingOrder
{
public virtual int Id { get; set; }
public virtual Order Order { get; set; }
}
映射:
Table("db_ReadingOrder");
Id(o => o.Id).Column("Id").GeneratedBy.Identity();
References(o => o.Order, "OrderId");
我想得到 ReadingOrder
,其中 orderId
等于 1(例如)。
但是当我尝试 FirstOrDefault
时,查询 returns null :
var readingO = _repositoryFactory.GetRepository<ReadingOrder>().FirstOrDefault(xz => xz.Order.Id == 1);
如果我得到所有这些并在应用后 FirstOrDefault
有效,但它很愚蠢:
var readingOrderList1 = _repositoryFactory.GetRepository<ReadingOrder>()
.GetAll().FirstOrDefault(xz => xz.Order.Id == 1);
存储库中的方法具有以下格式:
public T FirstOrDefault(Expression<Func<T, bool>> predicate)
{
return _session.Query<T>().FirstOrDefault(predicate);
}
简单的东西,但行不通。如果我选择正常的 属性,比如 Id
,一切都会按预期进行。
此外,如果我从日志中获取生成的查询并将其放入 sqlite,它会成功运行并返回读取顺序。 NHibernate 中有错误吗?是映射问题吗?还是 SQLite 的问题?
同样的场景在存储库中使用以下代码也能正常工作。
public virtual IEnumerable<T> Get(
Expression<Func<T, bool>> filter = null,
Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null,
string includeProperties = "")
{
IQueryable<T> query = _context.Set<T>();
if (filter != null)
{
query = query.Where(filter);
}
if (includeProperties != null)
foreach (var includeProperty in includeProperties.Split
(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
return query.ToList();
}
}
像这样修改您的class:
public class ReadingOrder
{
public virtual int Id { get; set; }
public virtual Order Order { get; set; }
public virtual int OrderId { get; set; } // Explicit and direct foreign Key
}
然后使用 OrderId
检索您的查询,而不是 Order.Id
:
var readingO = _repositoryFactory.GetRepository<ReadingOrder>()
.FirstOrDefault(xz => xz.OrderId == 1);
我认为有两种方法可以完成这项工作,或者将映射更改为:
Table("db_ReadingOrder");
Id(o => o.Id).Column("Id").GeneratedBy.Identity();
References(o => o.Order);
然后查询:
var readingO = _repositoryFactory.GetRepository<ReadingOrder>().FirstOrDefault(xz => xz.Order.Id == 1);
否则您也可以将映射更改为:
Table("db_ReadingOrder");
Id(o => o.Id).Column("Id").GeneratedBy.Identity();
References(o => o.Order).Column("OrderId");
然后查询:
var readingO = _repositoryFactory.GetRepository<ReadingOrder>().FirstOrDefault(xz => xz.Order.OrderId == 1);
好的,终于找到问题了:外键列的名称"OrderId"。
在这种情况下,Nhibernate 会查找 "Hibernate.Order",我不知道为什么,但是在我更改了列的名称之后,现在可以从 db 中检索该项目。谢谢大家的答案!我把赏金给了用户 Syed Farjad Zia Zaidi,因为他帮助我隔离了问题。很明显这是一个 Nhibernate 问题,所以再次感谢你。
有时这与动态全局过滤器有关,例如 IsDeleted
prop 的软删除方法,因此您需要获取被忽略的项目并使用一些方法,例如 .IgnoreQueryFilters()
in ef.
假设我们有以下模型:
public class ReadingOrder
{
public virtual int Id { get; set; }
public virtual Order Order { get; set; }
}
映射:
Table("db_ReadingOrder");
Id(o => o.Id).Column("Id").GeneratedBy.Identity();
References(o => o.Order, "OrderId");
我想得到 ReadingOrder
,其中 orderId
等于 1(例如)。
但是当我尝试 FirstOrDefault
时,查询 returns null :
var readingO = _repositoryFactory.GetRepository<ReadingOrder>().FirstOrDefault(xz => xz.Order.Id == 1);
如果我得到所有这些并在应用后 FirstOrDefault
有效,但它很愚蠢:
var readingOrderList1 = _repositoryFactory.GetRepository<ReadingOrder>()
.GetAll().FirstOrDefault(xz => xz.Order.Id == 1);
存储库中的方法具有以下格式:
public T FirstOrDefault(Expression<Func<T, bool>> predicate)
{
return _session.Query<T>().FirstOrDefault(predicate);
}
简单的东西,但行不通。如果我选择正常的 属性,比如 Id
,一切都会按预期进行。
此外,如果我从日志中获取生成的查询并将其放入 sqlite,它会成功运行并返回读取顺序。 NHibernate 中有错误吗?是映射问题吗?还是 SQLite 的问题?
同样的场景在存储库中使用以下代码也能正常工作。
public virtual IEnumerable<T> Get(
Expression<Func<T, bool>> filter = null,
Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null,
string includeProperties = "")
{
IQueryable<T> query = _context.Set<T>();
if (filter != null)
{
query = query.Where(filter);
}
if (includeProperties != null)
foreach (var includeProperty in includeProperties.Split
(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
return query.ToList();
}
}
像这样修改您的class:
public class ReadingOrder
{
public virtual int Id { get; set; }
public virtual Order Order { get; set; }
public virtual int OrderId { get; set; } // Explicit and direct foreign Key
}
然后使用 OrderId
检索您的查询,而不是 Order.Id
:
var readingO = _repositoryFactory.GetRepository<ReadingOrder>()
.FirstOrDefault(xz => xz.OrderId == 1);
我认为有两种方法可以完成这项工作,或者将映射更改为:
Table("db_ReadingOrder");
Id(o => o.Id).Column("Id").GeneratedBy.Identity();
References(o => o.Order);
然后查询:
var readingO = _repositoryFactory.GetRepository<ReadingOrder>().FirstOrDefault(xz => xz.Order.Id == 1);
否则您也可以将映射更改为:
Table("db_ReadingOrder");
Id(o => o.Id).Column("Id").GeneratedBy.Identity();
References(o => o.Order).Column("OrderId");
然后查询:
var readingO = _repositoryFactory.GetRepository<ReadingOrder>().FirstOrDefault(xz => xz.Order.OrderId == 1);
好的,终于找到问题了:外键列的名称"OrderId"。 在这种情况下,Nhibernate 会查找 "Hibernate.Order",我不知道为什么,但是在我更改了列的名称之后,现在可以从 db 中检索该项目。谢谢大家的答案!我把赏金给了用户 Syed Farjad Zia Zaidi,因为他帮助我隔离了问题。很明显这是一个 Nhibernate 问题,所以再次感谢你。
有时这与动态全局过滤器有关,例如 IsDeleted
prop 的软删除方法,因此您需要获取被忽略的项目并使用一些方法,例如 .IgnoreQueryFilters()
in ef.