2017-01-30 21 views
6

Na podstawie informacji z here.Jak zrobić ogólną funkcję za pomocą LINQ?

Znalazłem sposób usuwania sierot z Entity Framework.

public void SaveChanges() 
{ 
    context.ReportCards 
     .Local 
     .Where(r => r.Student == null) 
     .ToList() 
     .ForEach(r => context.ReportCards.Remove(r)); 

    context.SaveChanges(); 
} 

Zastanawiałem się, jak sprawić, by funkcję rodzajowy dla tej części, ponieważ może on być stosowany często:

context.ReportCards 
     .Local 
     .Where(r => r.Student == null) 
     .ToList() 
     .ForEach(r => context.ReportCards.Remove(r)); 

myślałem o czymś takim:

public void SaveChanges() 
{ 
    RemoveOrphans(Student, ReportCards) 
    context.SaveChanges(); 
} 

private void RemoveOrphans<T>(T sourceContext, T orphan) 
{  
    context.orphan 
     .Local 
     .Where(r => r.sourceContext == null) 
     .ToList() 
     .ForEach(r => context.orphan 
     .Remove(r)); 
} 

Ale oczywiście nie działa. Jakakolwiek rada?

+0

Dla 'Where' część po prostu przekazać w' Predicate' – TheLethalCoder

+0

Prawdopodobnie chcesz użyć '' context.Set . – juharr

Odpowiedz

6

Możesz napisać metodę rozszerzenia, które robi to samo:

public static void RemoveOrphans<TEntity>(this IDbSet<TEntity> entities, 
    Func<TEntity, bool> orphanPredicate) 
    where TEntity: class 
{ 
    entities.Local.Where(orphanPredicate).ToList().ForEach(e => entities.Remove(e)); 
} 

i używać go w ten sposób

context.ReportCards.RemoveOrphans(r => r.Student == null); 
context.SaveChanges(); 

Można również użyć prostej metody rodzajowe, które akceptuje IDbSet<TEntity> jako pierwszych parametrów, ale będzie nie może być tak czytelny.

RemoveOrphans(context.ReportCards, r => r.Student == null); 
context.SaveChanges(); 
+0

'.ToList()' nie jest leniwy. Używając '.AsEnumerable()' i napisz pętlę 'foreach'. – Oliver

+0

@Oliver dostaniesz "InvalidOperationException" w takim przypadku - nie wolno modyfikować kolekcji, która jest wymieniona –

+0

Och, tak. Masz rację. – Oliver

1

Coś takiego powinno działać:

private void RemoveOrphans<T>(Predicate<T> where) 
{ 
    var items = context.Set<T>().Where(where).ToList(); 
    if (items != null) 
    { 
     foreach (var item in items) 
     { 
      context.Set<T>().Remove(item); 
     } 
    } 
    context.SaveChanges(); 
} 

Zastosowanie:

RemoveOrphans<ReportCards>(r => r.Student == null); 
+0

'items' nigdy nie może mieć wartości' null' (ale puste). Tak więc kontrola zerowa nie jest potrzebna. – Oliver

Powiązane problemy