我使用的是Entity Framework 6.1,我有一个这样的代码:
Brand b;
using(var ctx = new KokosEntities())
{
try
{
b = ctx.Brands.Find(_brands[brandName].Id);
return b;
}
catch (Exception ex)
{
_logger.Log(LogLevel.Error, ex);
}
}
这会产生:
N'SELECT TOP (2)
[Extent1].[Id] AS [Id],
[Extent1].[Name] AS [Name],
[Extent1].[OpenCartId] AS [OpenCartId]
FROM [dbo].[Brands] AS [Extent1]
WHERE [Extent1].[Id] = @p0',N'@p0 int'
Find
方法返回单个结果,但它会生成TOP(2)
个查询,而不是1
。为什么呢?
注意:我确定我已将正确Id
传递给该方法,是的,Id
是主键。
答案 0 :(得分:13)
如果您查看DbSet<TEntity>.Find Method
的文档:
查找具有给定主键值的实体。
我看了Find
方法的源代码,发现:
/// <exception cref="T:System.InvalidOperationException">Thrown if multiple entities exist in the context with the primary key values given.</exception><exception cref="T:System.InvalidOperationException">Thrown if the type of entity is not part of the data model for this context.</exception><exception cref="T:System.InvalidOperationException">Thrown if the types of the key values do not match the types of the key values for the entity type to be found.</exception><exception cref="T:System.InvalidOperationException">Thrown if the context has been disposed.</exception>
public virtual TEntity Find(params object[] keyValues)
{
return this.GetInternalSetWithCheck("Find").Find(keyValues);
}
因此,如果有多个实体,该方法将抛出InvalidOperationException。
如果具有主键的上下文中存在多个实体,则抛出该异常 给出的值
在内部,对Find
的调用不会转化为Single/SingleOrDefault
;相反,一个简单的循环用于检查多个实体。
由于该方法特定于主键,因此在多个实体的情况下应该抛出异常。这就是它生成查询以选择至少两个记录的原因。与Single
电话类似。
答案 1 :(得分:9)
我在猜测下会转换为Single
来电或类似的东西。在这种情况下,LINQ希望确保只有1个结果。如果返回了2条记录,则可以抛出。