web-dev-qa-db-fra.com

Meilleur moyen de vérifier si un objet existe dans Entity Framework?

Quel est le meilleur moyen de vérifier si un objet existe dans la base de données du point de vue des performances? J'utilise Entity Framework 1.0 (ASP.NET 3.5 SP1).

95
Freddy

Si vous ne voulez pas exécuter SQL directement, la meilleure solution consiste à utiliser Any () . En effet, Any () reviendra dès qu'il trouvera une correspondance. Une autre option est Count () , mais il faudra peut-être vérifier chaque ligne avant de retourner.

Voici un exemple d'utilisation:

if (context.MyEntity.Any(o => o.Id == idToMatch))
{
    // Match!
}

Et dans vb.net

If context.MyEntity.Any(function(o) o.Id = idToMatch) Then
    ' Match!
End If
196
Alex Angas

Du point de vue des performances, je suppose qu’une requête SQL directe utilisant la commande EXISTE serait appropriée. Voir ici pour savoir comment exécuter SQL directement dans Entity Framework: http://blogs.Microsoft.co.il/blogs/gilf/archive/2009/11/25/execute-t-sql-statements-in-entity- framework-4.aspx

7
Konamiman

Je devais gérer un scénario dans lequel le pourcentage de doublons fournis dans les nouveaux enregistrements de données était très élevé et que des milliers d'appels à la base de données étaient alors passés pour vérifier les doublons (le processeur envoyait donc beaucoup de temps à 100%). En fin de compte, j'ai décidé de conserver les 100 000 derniers enregistrements en mémoire cache. De cette façon, je pouvais vérifier les doublons par rapport aux enregistrements mis en cache, ce qui était extrêmement rapide par rapport à une requête LINQ par rapport à la base de données SQL, puis écrire de nouveaux enregistrements véritablement dans la base de données (ainsi que de les ajouter au cache de données, ce qui triés et parés pour garder sa longueur gérable).

Notez que les données brutes étaient un fichier CSV contenant de nombreux enregistrements individuels devant être analysés. Les enregistrements de chaque fichier consécutif (à raison d'environ 1 toutes les 5 minutes) se chevauchaient considérablement, d'où le pourcentage élevé de doublons.

En bref, si vous avez des données brutes horodatées qui arrivent, en ordre, l'utilisation d'un cache mémoire peut aider à la vérification de la duplication des enregistrements.

4
ProfNimrod

Je sais que c’est un très vieux fil de discussion mais que si quelqu'un comme moi avait besoin de cette solution, voici ce que j’ai utilisé sur VB.NET.

Private Function ValidateUniquePayroll(PropertyToCheck As String) As Boolean
    // Return true if Username is Unique
    Dim rtnValue = False
    Dim context = New CPMModel.CPMEntities
    If (context.Employees.Any()) Then ' Check if there are "any" records in the Employee table
        Dim employee = From c In context.Employees Select c.PayrollNumber ' Select just the PayrollNumber column to work with
        For Each item As Object In employee ' Loop through each employee in the Employees entity
            If (item = PropertyToCheck) Then ' Check if PayrollNumber in current row matches PropertyToCheck
                // Found a match, throw exception and return False
                rtnValue = False
                Exit For
            Else
                // No matches, return True (Unique)
                rtnValue = True
            End If
        Next
    Else
        // The is currently no employees in the person entity so return True (Unqiue)
        rtnValue = True
    End If
    Return rtnValue
End Function
4
Kevin Morrissey

J'ai eu quelques problèmes avec ceci - mon EntityKey est composé de trois propriétés (PK avec 3 colonnes) et je ne voulais pas vérifier chacune des colonnes car cela serait moche . toutes les entités.

Une autre raison à cela est que je n'aime pas attraper UpdateExceptions à chaque fois.

Un peu de réflexion est nécessaire pour obtenir les valeurs des propriétés de la clé.

Le code est implémenté comme une extension pour simplifier l'utilisation en tant que: 

context.EntityExists<MyEntityType>(item);

Regarde:

public static bool EntityExists<T>(this ObjectContext context, T entity)
        where T : EntityObject
    {
        object value;
        var entityKeyValues = new List<KeyValuePair<string, object>>();
        var objectSet = context.CreateObjectSet<T>().EntitySet;
        foreach (var member in objectSet.ElementType.KeyMembers)
        {
            var info = entity.GetType().GetProperty(member.Name);
            var tempValue = info.GetValue(entity, null);
            var pair = new KeyValuePair<string, object>(member.Name, tempValue);
            entityKeyValues.Add(pair);
        }
        var key = new EntityKey(objectSet.EntityContainer.Name + "." + objectSet.Name, entityKeyValues);
        if (context.TryGetObjectByKey(key, out value))
        {
            return value != null;
        }
        return false;
    }
4
Sven

Je vérifie juste si l'objet est nul, cela fonctionne à 100% pour moi

    try
    {
        var ID = Convert.ToInt32(Request.Params["ID"]);
        var Cert = (from cert in db.TblCompCertUploads where cert.CertID == ID select cert).FirstOrDefault();
        if (Cert != null)
        {
            db.TblCompCertUploads.DeleteObject(Cert);
            db.SaveChanges();
            ViewBag.Msg = "Deleted Successfully";
        }
        else
        {
            ViewBag.Msg = "Not Found !!";
        }                           
    }
    catch
    {
        ViewBag.Msg = "Something Went wrong";
    }
2
user4584103

Pourquoi ne pas le faire?

var result= ctx.table.Where(x => x.UserName == "Value").FirstOrDefault();

if(result?.field == value)
{
  // Match!
}
0
Matheus Miranda