gpt4 book ai didi

c# - 如何在我的自定义集合中模仿 IQueryable.Include(Expression> path) 的功能?

转载 作者:太空狗 更新时间:2023-10-29 23:51:48 24 4
gpt4 key购买 nike

首先,介绍一下背景。我正在使用 ASP.NET Web API 和 Entity Framework 5 开发 REST API,但是系统的要求是在我的 ApiController 和我的 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.FooFoo.Bars导航属性未填充,因为这会使具体化过程复杂化。因此,在物化完成后,Materialization.FoosMaterialization.Bars包含通过外键属性而不是导航属性相互引用的对象集合(即所有导航属性的值为 null 或空 List<T> s)。我希望能够在我的 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()扩展方法?

最佳答案

这里有几个选项:

  1. 考虑使用另一个上下文来实现您的 MaterializationRepositories,并让它得到内存数据库的支持,例如 Effort ,如果现在仍然有效的话。
  2. 自己在 Materialization 上重新实现“包含”功能。可以分解表达式以查找导航属性的类型。使用命名约定,您可以计算出需要查询哪些外键属性以获得正确的标识符。要查找目标存储库,您可以使用物化反射来查找导航属性类型的 IEnumerable 类型的公共(public)属性。只要您知道目标实体的主键名称(例如,按照惯例),您就可以使用外键值找到它。

如果您有少量实体类型,您可能最好使用某种 switch 语句并手动执行其中一些,而不是通过反射。

抱歉,这不是一个完整的实现过程,但我希望它能引导正确的方向。

关于c# - 如何在我的自定义集合中模仿 IQueryable<T>.Include(Expression<Func<T,TProperty>> path) 的功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14964345/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com