Entity Framework – Méthode correcte pour vérifier des enregistrements individuels avant de les utiliser

Pour obtenir une LISTE de disques, je fais normalement quelque chose comme:

var efCompany = from a in _dbRiv.Company where a.CompanyId == companyFeedInfo.CompanyId select a; 

Pour obtenir un seul enregistrement, lorsque je sais que j’utilise le PK pour le récupérer, j’utilise quelque chose comme:

 var efCompany = (from a in _dbRiv.Company where a.CompanyId == companyFeedInfo.CompanyId select a).First(); 

Maintenant, en utilisant l’approche d’enregistrement unique, si la PC est une valeur erronée (comme elle le fait délibérément lors des tests), la deuxième ligne génère une erreur.

Quelle est la meilleure méthode pour obtenir un seul enregistrement et le gérer?

Utilisez SingleOrDefault si vous attendez 0 ou 1, ou FirstOrDefault si vous avez simplement besoin du premier enregistrement sur plusieurs, mais que vous puissiez gérer 0. Les deux FirstOrDefault la valeur par défaut pour le type (généralement null) s’il n’y a pas de résultats.

En passant, les requêtes de ce type sont généralement plus lisibles (IMO) sans utiliser d’expression de requête. Vous pouvez donc obtenir quelque chose comme:

 var efCompany = _dbRiv.Company .Where(a => a.CompanyId == companyFeedInfo.CompanyId) .SingleOrDefault(); if (efCompany != null) { // Use it } else { // Report to user, or whatever } 

Les expressions de requête sont excellentes lorsque vous utilisez plusieurs opérateurs ou que vous réalisez des tâches relativement complexes telles que des jointures. Toutefois, si vous venez de recevoir une clause where ou une projection, cette “notation par points” est plus simple. Cela fonctionne également mieux lorsque vous devez appeler une méthode comme FirstOrDefault à la fin.

Notez que SingleOrDefault() et FirstOrDefault() ne vous permettront pas de spécifier la valeur par défaut.

Il existe DefaultIfEmpty() , qui vous permet de spécifier la valeur par défaut à renvoyer s’il n’y a aucun élément dans l’énumérable. Vous pouvez combiner celui-ci avec First() (comme dans DefaultIfEmpty().First() ) pour obtenir FirstOrDefault() comportement semblable à FirstOrDefault() et un lambda pour créer une nouvelle instance et l’append à l’ensemble.

Si vous avez juste besoin de vérifier l’existence d’un enregistrement, vous pouvez également utiliser Any() . Toutefois, cela entraînera deux requêtes si vous devez traiter l’enregistrement s’il existe.

 var efCompany = _dbRiv.Company .SingleOrDefault(a => a.CompanyId == companyFeedInfo.CompanyId); if (efCompany != null) { // Use it } else { // Report to user, or whatever } 

Vous pouvez aussi utiliser

 _dbRiv.Company.find(#id) 

si vous recherchez un disque sans ses modèles inclus.

Ou

 _dbRiv.Company.FirstOrDefault(x => x.Id == #id); 

Je recommande FirstOrDefault à SingleOrDefault en raison de ses performances. Avec SingleOrDefault, il doit parsingr la table entière et s’assurer qu’il n’ya qu’un seul enregistrement avec l’ID. Avec FirstOrDefault, il peut simplement aller jusqu’à ce qu’il trouve cet identifiant, puis s’arrête. Sur une grande table, chaque requête vous fera gagner un temps précieux.

Vous pouvez également utiliser AsNoTracking pour améliorer la consommation de mémoire si vous n’avez pas besoin de suivre les modifications apscopes au modèle. Par exemple, si vous le renvoyez via une demande de repos sans appeler de sauvegarde.