2016-01-23 11 views
5

So kombinieren Sie Find() mit AsNoTracking(), wenn Sie Abfragen an einen EF-Kontext senden, um zu verhindern, dass das zurückgegebene Objekt verfolgt wird. Das kann ich nichtWie kombiniere ich Find() und AsNoTracking()?

_context.Set<Entity>().AsNoTracking().Find(id); 

Wie kann ich das tun? Ich verwende EF Version 6.

Hinweis: Ich möchte nicht SingleOrDefault() oder Where verwenden. Ich kann einfach nicht, weil der Parameter Id generisch ist und es ist ein struct und ich kann Operator == für Generics in diesem Fall nicht anwenden.

+0

„* Ich kann es einfach 't * "ist kein durchsetzbarer Anspruch, es sei denn, Sie können uns zeigen, warum Sie dies nicht können. Wenn man das Wissen der SO-Community kennt, kann man das vielleicht, man weiß einfach nicht ** wie **. – Tommy

+1

@Tommy danke, fügte weitere Details hinzu. –

+0

Sie sollten 'Equals' anstelle von' == 'verwenden können, wenn das Ihr einziges Problem ist, aber ich vermute, dass es auch noch andere Probleme gibt, die Sie noch nicht mit Ihrer Frage teilen: Es gibt keine Standardmethode zum Extrahieren zum Beispiel die Schlüsseleigenschaften einer Entität. – hvd

Antwort

6

Also statt Verwenden Sie AsNoTracking(), was Sie tun können, ist Find() und dann trennen Sie es aus dem Kontext. Ich glaube, das gibt Ihnen das gleiche Ergebnis wie AsNoTracking() neben dem zusätzlichen Aufwand für die Verfolgung der Entität. Weitere Informationen finden Sie unter EntityState.

var entity = Context.Set<T>().Find(id); 
Context.Entry(entity).State = EntityState.Detached; 
return entity; 
4
<context>.<Entity>.AsNoTracking().Where(s => s.Id == id); 

Find() macht keinen Sinn, mit AsNoTracking() weil Find soll der Lage sein, verfolgt Einheiten zurückzukehren, ohne mit AsNoTracking zur Datenbank .. Ihre einzige Option zu gehen entweder Where oder First oder Single...

+1

Kann das nicht benutzen, weil die 'Id' generisch ist und ich den Operator' = '' nicht mit Generics verwenden kann :) –

+0

@HeidelBerGensis Kann Sie zeigen Ihr vollständiges Code-Snippet, warum Generic in diesem Fall nicht funktionieren kann? –

+1

überprüfen Sie [diesen Beitrag] (http://stackoverflow.com/questions/390900/cantoperator-be-applied-to-generic-types-in-c), für mich ist der TKey Strukturtyp. Also, ich kann nur nicht. –

0

Nun, ich denke, wenn Sie das wirklich wollen, können Sie versuchen, Ihren Ausdruck selbst zu erstellen. Ich nehme an, Sie haben eine Basis-Entity-Klasse, die generisch ist und von der die generische Key-Eigenschaft kommt. Ich nannte diese Klasse KeyedEntityBase<TKey>, TKey ist der Typ des Schlüssels (wenn Sie keine solche Klasse haben, ist das in Ordnung, das einzige, was ich für die generische Einschränkung verwendet habe). Dann können Sie eine Erweiterungsmethode wie diese schaffen den Ausdruck selbst zu bauen:

public static class Extensions 
{ 
    public static IQueryable<TEntity> WhereIdEquals<TEntity, TKey>(
      this IQueryable<TEntity> source, 
      Expression<Func<TEntity, TKey>> keyExpression, 
      TKey otherKeyValue) 
      where TEntity : KeyedEntityBase<TKey> 
    { 
    var memberExpression = (MemberExpression)keyExpression.Body; 
    var parameter = Expression.Parameter(typeof(TEntity), "x"); 
    var property = Expression.Property(parameter, memberExpression.Member.Name); 
    var equal = Expression.Equal(property, Expression.Constant(otherKeyValue)); 
    var lambda = Expression.Lambda<Func<TEntity, bool>>(equal, parameter); 
    return source.Where(lambda); 
    } 
} 

Und dann können Sie es wie folgt verwenden (für eine ganze Zahl Schlüsseltyp):

context.Set<MyEntity>.AsNoTracking().WhereIdEquals(m=>m.Id, 9).ToList(); 
Verwandte Themen