2009-11-26 10 views

risposta

181

Se non si desidera eseguire direttamente SQL, il modo migliore è quello di 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 
+0

E in VB If (context.MyEntity.Any (o => o.Id <> idToMAtch)) Quindi 'Questa è una corrispondenza! Fine Se Siamo spiacenti, questo non è nel codice, non sono riuscito a capire come farlo! –

+0

Pensa che intendi o.Id <> idToMatch NON è uguale a una corrispondenza – Colin

+0

e se eseguo una ricerca per nome e voglio ottenere l'ID se esiste? –

7

Dal punto di vista delle prestazioni, suppongo che una query SQL diretta che utilizza il comando EXISTS sia appropriata. 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

+0

Sì, buona idea ma non limitato a una versione precedente del framework di entità. – Freddy

+3

Qualsiasi() funzione delle mappe risposta accettate su EXISTS() – RonaldPaguay

3

ho avuto qualche problema con questo - la mia EntityKey si compone di tre proprietà (PK con 3 colonne) e non volevo controllare ognuna delle colonne perché sarebbe brutto. Ho pensato a una soluzione che funzioni sempre con tutte le entità.

Un altro motivo per questo è che non mi piace prendere sempre tutte le eccezioni.

Un po 'di riflessione è necessario per ottenere i valori delle proprietà chiave.

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

context.EntityExists<MyEntityType>(item); 

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

So che questo è un filo molto vecchio, ma solo in caso qualcuno come me esigenze questa soluzione ma in VB.NET ecco cosa 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 
+0

Non so come usare Lambda in VB ma in C# questo è equivalente: return! context.Employees.Any (c => c.PayrollNumber == PropertyToCheck). Questo evita di restituire tutti i risultati e di eseguire il looping in memoria. – Colin

+1

@Colin questa è una buona aggiunta Ho trascurato il problema di memoria con il codice precedente, in VB il codice è context.Employees.Any (c => c.PayrollNumber <> PropertyToCheck). Ora ho aggiunto questo al mio codice. –

+0

Kevin, penso che potresti dover tornare indietro e correggere il tuo codice. La tua logica sta sicuramente ritornando vera se ci sono dei numeri sui salari che non corrispondono, piuttosto che veri quando non ci sono numeri di retribuzione corrispondenti. – Colin

3

ho dovuto gestire uno scenario in cui la percentuale di duplicati fornite nei nuovi set di dati è stato molto elevato, e tante migliaia di chiamate al database sono stati fatti per verificare la presenza di duplicati (in modo che il CPU inviato un sacco di tempo al 100%). Alla fine ho deciso di mantenere gli ultimi 100.000 record memorizzati nella memoria. In questo modo ho potuto controllare i duplicati contro i record memorizzati nella cache che è stata estremamente veloce rispetto ad una query LINQ contro il database SQL, e poi scrivere qualsiasi genuinamente nuovi record al database (così come aggiungerli alla cache di dati, che ho anche ordinato e tagliato per mantenere la sua lunghezza gestibile).

Si noti che i dati grezzi era un file CSV che conteneva molti record individuali che dovevano essere analizzato. I record in ogni file consecutivi (che è venuto ad una velocità di circa 1 ogni 5 minuti) sovrapposti notevolmente, quindi l'alta percentuale di duplicati.

In breve, se avete timestamped dati grezzi in arrivo, più o meno in ordine, quindi utilizzando una cache di memoria potrebbe aiutare con il controllo di registrazione di duplicazione.

+1

Molte volte gli sviluppatori hanno ideato il tuo scenario, potrebbero essere con alcuni colpi di scena. Vorrei chiederti di tradurre la tua soluzione in C# in modo che noi e molti futuri sviluppatori ne traggano vantaggio. +1. Mi piacerebbe che la soluzione venisse estesa anche a un post sul blog! :) – sangam

1

ho solo controllare se oggetto è nullo, 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"; 
    } 
0

Perché non farlo?

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

if(result.field == value) 
{ 
    // Match! 
} 
Problemi correlati