2013-02-19 18 views
5

Po pierwsze, małe tło. Zajmuję się tworzeniem REST API przy użyciu ASP.NET Web API i Entity Framework 5, jednak wymagania systemu są takie, że kilka warstw logiki siedzi pomiędzy moimi ApiControllers i moim DbContext. Te warstwy logiki wiążą się z odłączaniem moich obiektów od DbContext, stosowaniem zestawów hipotetycznych zmian w elementach w pamięci (proces nazywam zestawem zmian), co pozwala użytkownikom na sprawdzenie nowego stanu systemu, jeśli zmiany zostaną zastosowane. Nowy stan jednostek nie jest natychmiast zapisywany w bazie danych. Zamiast tego materializacja jest przechowywana w pamięci na serwerze WWW, a użytkownicy mogą sprawdzać bieżące dane lub jedną z wielu materializacji różnych zestawów zmian.Jak naśladować funkcjonalność ścieżki IQueryable <T> .Include (Wyrażenie <Func <T,TProperty>>) w mojej kolekcji niestandardowej?

Teraz za mój problem.

public interface IIdentifiable 
{ 
    long Id { get; set; } 
} 

public class Foo : IIdentifiable 
{ 
    public long Id { get; set; } 
    public string Name { get; set; } 
    public List<Bar> Bars { get; set; } // Navigation Property 
} 

public class Bar : IIdentifiable 
{ 
    public long Id { get; set; } 
    public string Name { get; set; } 
    public long FooId { get; set; } // Foreign Key Property 
    public Foo Foo { get; set; } // Navigation Property 
} 

public class Materialization 
{ 
    IEnumerable<Foo> Foos { get; set; } 
    IEnumerable<Bar> Bars { get; set; } 
} 

public interface IRepository<TItem> : IQueryable<TItem>, ICollection<TItem>, IDisposable 
    where TItem : class, IIdentifiable 
{ 
    IRepository<TItem> Include<TProperty>(Expression<Func<TItem, TProperty>> path); 
    // Other methods 
} 

public class MateriailizationRepository<TItem> : IRepository<TItem> 
    where TItem : class, IIdentifiable 
{ 
    private Materialization _materialization; 

    public MateriailizationRepository(Materialization materialization) 
    { 
     _materialization = materialization; 
    } 

    public IRepository<TItem> Include<TProperty>(Expression<Func<TItem, TProperty>> path) 
    { 
     // Populate navigation property indicated by "path" 
    } 

    // Other methods 
} 

Każdy pasek ma właściwość klucza obcego wskazującego Foo należy do ale właściwości nawigacyjnych Bar.Foo i Foo.Bars nie są wypełniane, jak będzie to skomplikować z procesu materializacji. Zatem po zakończeniu materializacji, Materialization.Foos i Materialization.Bars zawierają kolekcje obiektów, które odnoszą się do siebie nawzajem przez właściwości klucza obcego, ale nie przez właściwości nawigacyjne (tj. Wartości wszystkich właściwości nawigacyjnych są puste lub puste List<T> s). Chcę móc zrobić coś takiego w moim ApiController.

public IQueryable<Foo> Get (bool includeBars = false) 
{ 
    Materialization materialization; 

    // Materialize 

    using (IRepository<Foo> repository = new MateriailizationRepository<Foo>(materialization)) 
    { 
     IRepository<Foo> query = repository; 

     if (includeBars) 
      query = query.Include(f => f.Bars); 

     return query; 
    } 
} 

MateriailizationRepository<Foo> jest podstawowym obowiązkiem jest sprowadzić zmaterializował Foo obiektów, ale ponieważ ma odniesienie do całego Materialization Chciałbym móc to zmaterializowanych Bar obiektów z Materiailization.Bars na żądanie.

W jaki sposób mam wdrożyć MateriailizationRepository.Include(), aby naśladować metodę rozszerzenia IQueryable.Include()?

+0

Sprawdź to. Wygląda na to, co chcesz osiągnąć: http: // stackoverflow.com/questions/19665887/Iqueryable-function-like-include-but-for-a-single-entity/19666557 # 19666557 – Aidin

+0

Czy jest to ogólny api, czy jakaś dziedzina nauki? – Marius

Odpowiedz

0

Oto kilka opcji:

  1. przyjrzeć przy użyciu innego kontekstu w celu realizacji swoich MaterializationRepositories i są to poparte w pamięci bazy danych, takich jak Effort, jeśli nadal pracuje obecnie.
  2. Ponownie zaimplementuj funkcję "Uwzględnij" w Materializacji. Wyrażenie można zepsuć, aby znaleźć typ właściwości nawigacji. Korzystając z konwencji nazewnictwa, można ustalić, jaką właściwość klucza obcego należy przesłuchać, aby uzyskać poprawny identyfikator. Aby znaleźć repozytorium docelowe, można użyć refleksji nad Materializacją, która szuka właściwości publicznej typu IEnumerable typu właściwości nawigacji. Tak długo, jak znasz nazwę klucza podstawowego jednostki docelowej (zgodnie z konwencją, powiedz), możesz użyć wartości klucza obcego, aby ją znaleźć.

Jeśli masz niewielką liczbę typów jednostek, lepiej byłoby mieć instrukcję zmiany i zrobić ją ręcznie, a nie poprzez odbicie.

Przepraszam, że nie jest to w pełni zrealizowane wdrożenie, ale mam nadzieję, że prowadzi to we właściwym kierunku.

Powiązane problemy