首先,一点背景。我正在使用 ASP.NET Web API 和 Entity Framework 5 开发一个 REST API,但是系统的要求是在我的 ApiControllers 和我的 DbContext 之间存在几层逻辑。这些逻辑层涉及将我的实体从 DbContext 中分离出来,将一组假设更改应用于内存中的实体(我称之为更改集的具体化的过程),然后允许用户在这些更改获得时检查系统的新状态应用。实体的新状态不会立即保存到数据库中。相反,具体化保存在 Web 服务器的内存中,用户可以检查当前数据或各种变更集的众多具体化之一。
现在解决我的问题。
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
}
每个 Bar 都有一个外键属性,指示Foo
它属于哪个,但不会填充Bar.Foo
和Foo.Bars
导航属性,因为这会使具体化过程复杂化。因此,在物化完成后,Materialization.Foos
包含Materialization.Bars
通过外键属性而不是导航属性相互引用的对象集合(即所有导航属性的值都是 null 或空List<T>
)。我希望能够在我的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>
的主要职责是获取物化Foo
对象,但由于它引用了整个对象,因此Materialization
我希望能够按需包含物化Bar
对象。Materiailization.Bars
我将如何实施MateriailizationRepository.Include()
以模仿IQueryable.Include()
扩展方法?