Domanda

Qual è il modo migliore per verificare se esiste un oggetto nel database dal punto di vista delle prestazioni? Sto usando Entity Framework 1.0 (ASP.NET 3.5 SP1).

È stato utile?

Soluzione

Se non si desidera eseguire direttamente SQL, il modo migliore è utilizzare Any () . Questo perché Any () tornerà non appena trova una corrispondenza. Un'altra opzione è Count () , ma potrebbe essere necessario controllare ogni riga prima di tornare.

Ecco un esempio di come usarlo:

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

E in vb.net

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

Altri suggerimenti

Da un punto di vista delle prestazioni, suppongo che una query SQL diretta utilizzi Il comando EXISTS sarebbe appropriato. Vedi qui per come eseguire SQL direttamente in Entity Framework: http://blogs.microsoft.co.il/blogs/gilf/archive/2009/11/25/execute-t-sql-statements-in-entity -Framework-4.aspx

Ho dovuto gestire uno scenario in cui la percentuale di duplicati forniti nei nuovi record di dati era molto alta e sono state fatte così tante migliaia di chiamate al database per verificare la presenza di duplicati (quindi la CPU ha inviato molto tempo a 100 %). Alla fine ho deciso di tenere in memoria gli ultimi 100.000 record. In questo modo ho potuto verificare la presenza di duplicati rispetto ai record memorizzati nella cache che era estremamente veloce rispetto a una query LINQ sul database SQL e quindi scrivere qualsiasi record veramente nuovo nel database (nonché aggiungerli alla cache dei dati, che ho anche ordinati e tagliati per mantenerne la lunghezza gestibile).

Si noti che i dati non elaborati erano un file CSV che conteneva molti record individuali che dovevano essere analizzati. I record in ciascun file consecutivo (che è arrivato a una velocità di circa 1 ogni 5 minuti) si sono sovrapposti considerevolmente, quindi l'elevata percentuale di duplicati.

In breve, se sono in arrivo dati grezzi con data e ora, praticamente in ordine, l'utilizzo di una cache di memoria potrebbe aiutare con il controllo della duplicazione dei record.

So che questo è un thread molto vecchio, ma solo nel caso qualcuno come me abbia bisogno di questa soluzione, ma in VB.NET ecco quello che ho usato in base alle risposte sopra.

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

Ho avuto qualche problema con questo - il mio EntityKey è costituito da tre proprietà (PK con 3 colonne) e non volevo controllare ciascuna delle colonne perché sarebbe brutto. Ho pensato a una soluzione che funzioni sempre con tutte le entità.

Un altro motivo di ciò è che non mi piace catturare UpdateExceptions ogni volta.

È necessario un po 'di Reflection per ottenere i valori delle proprietà chiave.

Il codice è implementato come estensione per semplificare l'utilizzo come:

context.EntityExists<MyEntityType>(item);

Dai un'occhiata:

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

Controllo solo se l'oggetto è null, funziona al 100% per me

    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";
    }

Perché non farlo?

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

if(result?.field == value)
{
  // Match!
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top