2016-01-23 27 views
5

, döndürülen nesnenin izlenmesini önlemek için bir EF bağlamında sorgu yaparken AsNoTracking() ile nasıl birleştirilir. Ben yapamayacağım budur. Bunu nasıl yapabilirim? EF sürüm 6 kullanıyorum.Find() ve AsNoTracking() nasıl birleştirilir?

Not: SingleOrDefault() veya Where'u kullanmak istemiyorum. Ben sadece Id parametresi jenerik ve bir struct olduğundan ve bu durumda jenerikler için operatör == uygulayamıyorum çünkü yapamam.

+0

"* Sadece can Bize neden yapamayacağınızı gösteremedikçe 't *' uygulanabilir bir iddia değildir. SO topluluğunun bilgisi göz önünde bulundurulduğunda, belki de, sadece bilmiyorsunuz ** nasıl **. – Tommy

+1

@Tommy teşekkürler, daha fazla ayrıntı ekledi. –

+0

'==' işlevini kullanmak yerine '==' kullanabilmeniz gerekir, çünkü tek sorun budur, ama yine de sorunuzda paylaşmamanız gereken başka sorunlar da olabileceğinden şüpheleniyorum: standart bir ayıklama yöntemi yok Örneğin, bir varlığın anahtar özellikleri. – hvd

cevap

6

Single... Bunun yerine her iki olduğu AsNoTracking() kullanarak yapabileceğiniz şey Find() ve daha sonra bağlamdan ayırmaktır. Bu durumun, varlığın izlenmesinin ek yükünün yanı sıra AsNoTracking() ile aynı sonucu verdiğine inanıyorum. Daha fazla bilgi için bkz. 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() veritabanına gitmeden izlenen varlıkları iade edebilmek gerekiyordu AsNoTracking()Find çünkü ile mantıklı değil .. AsNoTracking ile tek seçenek Where veya First veya

+1

Bunu kullanamazsınız, çünkü 'Id' jeneriktir ve '== 'operatörünü kullanamazsınız :) –

+0

@HeidelBerGensis Can Tam kod snippet'inizi, jenerikin bu durumda neden işe yaramadığını gösterecek misiniz? –

+1

[bu gönderiyi kontrol edin] (http://stackoverflow.com/questions/390900/cant-operator-be-applied-to-generic-types-in-c), benim için TKey yapı tipi. Yani, yapamam. –

0

Eh, bunu gerçekten yapmak istiyorsanız, size ifadeyi kendiniz oluşturmayı deneyebilirsiniz sanırım. Genel bir temel varlık sınıfınız olduğunu ve genel anahtar özelliğinin nereden geldiğini tahmin ediyorum. Bu sınıfı KeyedEntityBase<TKey> olarak adlandırdım, TKey anahtarın türündedir (eğer böyle bir sınıfınız yoksa, sorun değil, bunun için kullandığım tek şey genel kısıtlamadır).

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

Ve sonra, (bir tamsayı anahtar türü için) bu gibi kullanabilirsiniz: Sonra ifadeyi kendini inşa etmek için böyle bir uzatma yöntemi oluşturabilir

context.Set<MyEntity>.AsNoTracking().WhereIdEquals(m=>m.Id, 9).ToList(); 
İlgili konular