【发布时间】:2018-01-29 14:49:00
【问题描述】:
我需要使用实体框架检查客户代码是否已经存在于数据库中。理想情况下,我会像这样编写普通的 sql 查询:
select id from dbo.Customer where RecActive = 1 and Code = 'xxx';
如果查询结果为空,则表示代码'xxx'的客户还不存在。在实体框架中,有多种编写方式,但我正在寻找上面最接近的一种。 注意:代码字段上有唯一索引
using (var context = new CustomerContext())
{
// not very efficient as it reads all columns
return context.Customers.Where(c => c.RecActive && c.Code == customerCode).SingleOrDefault() != null ? true : false;
return context.Customers.Where(c => c.RecActive && c.Code == customerCode).Count() > 0 ? true : false;
// translates to this query:
// exec sp_executesql N'SELECT [Limit1].[Id] AS [Id]
// FROM ( SELECT TOP (2)
// [Extent1].[Id] AS [Id]
// FROM [dbo].[Customer] AS [Extent1]
// WHERE ([Extent1].[RecActive] = 1) AND (([Extent1].[Code] =
// @p__linq__0) OR (([Extent1].[Code] IS NULL) AND
// (@p__linq__0 IS NULL)))
// ) AS [Limit1]',N'@p__linq__0 nvarchar(4000)',@p__linq__0=N'xxx'
int a = context.Customers.Where(c => c.RecActive && c.Code == customerCode).Select(c => c.Id).SingleOrDefault();
return a > 0 ? true : false;
return context.Customers.Where(c => c.RecActive && c.Code == customerCode).Any();
}
也许还有其他好的(性能替代)?注意:我必须使用实体框架 linq 而不是原始查询(我真的很喜欢),因为 linq 在整个项目中一直使用。
【问题讨论】:
-
return context.Customers.Where(c => c.RecActive && c.Code == customerCode).Any();
-
为什么你需要这样的东西?您是否正在尝试编写 UPSERT 方法?如果
Code是主键,EF 将在插入或更新之前自行执行检查。如果您出于其他原因想要检查是否存在,请使用Any()。如果您想要 ID,请使用.Where()...).Select(c=>c.id) -
为什么
<condition> ? true : false- 对我来说似乎是多余的。 -
Any()可能会在其查询中使用select null,而不是select id。这是一个非常小的区别,但问题在于既要询问它是否与原始查询的轻微低效率相匹配,又要询问它是性能最高的。
标签: c# entity-framework linq linq-to-sql