简体   繁体   中英

Efficiently check if record exists in database using Entity framework LINQ

I need to check if customer by code already exists in the database using entity framework. Ideally I would write plain sql query like this:

select id from dbo.Customer where RecActive = 1 and Code = 'xxx';

If query result is empty, it means customer by code 'xxx' does not exist yet. In entity framework there are multiple ways to write this, but I'm looking the one nearest above . Note: Code field has unique index on it

  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();
  }

Perhaps any other good (performance alternative)? Note: I have to use entity framework linq and not raw queries (which I would really like) as linq is used throughout whole project consistently.

If you want to check for existence only, use .Any() . If you want to retrieve the ID(s) that match the criteria, use Select , eg :

 context.Customers
        .Where(c => c.RecActive && c.Code == customerCode)
        .Select(c => c.id);

If multiple IDs are a valid result, your method should return an array of strings/integers, whatever the type of id is. You can return an array of IDs with .ToArray();

 return context.Customers
               .Where(c => c.RecActive && c.Code == customerCode)
               .Select(c => c.id)
               .ToArray();

If you don't expect multiple IDs, you have to decide what to do if you get multiples results:

  • FirstOrDefault() will return the first ID without throwing if there are multiple results.
  • SingleOrDefault() will throw if there are multiple results preventing the use of a possibly invalid ID.

For example:

return context.Customers.Where(c => c.RecActive && c.Code == customerCode)
               .Select(c => c.id)
               .SingleOrDefault();

由于您的代码会忽略实际 ID,并且仅返回其存在的true / false指示,因此您可以通过一次调用Any

return context.Customers.Any(c => c.RecActive && c.Code == customerCode);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM