尝试使用通用实体框架

Rob*_*ert 7 c# generics entity-framework

让我先说一下,我不确定这是否可行.我正在学习泛型,我的应用程序中有几个存储库.我正在尝试创建一个接受泛型类型的接口,并将其转换为所有存储库可以继承的东西.现在回答我的问题.

public interface IRepository<T>
{
    IEnumerable<T> FindAll();
    IEnumerable<T> FindById(int id);
    IEnumerable<T> FindBy<A>(A type);
}
Run Code Online (Sandbox Code Playgroud)

是否可以使用通用来确定要查找的内容?

public IEnumerable<SomeClass> FindBy<A>(A type)
{
    return _context.Set<SomeClass>().Where(x => x. == type); // I was hoping to do x.type and it would use the same variable to search.
}
Run Code Online (Sandbox Code Playgroud)

为了澄清一点,我考虑成为一个字符串,int或我想要搜索的任何类型.我希望的是我可以说x.something其中的东西等于传入的变量.

我可以使用.将任何存储库设置为我的dbcontext

public IDbSet<TEntity> Set<TEntity>() where TEntity : class
{
    return base.Set<TEntity>();
}
Run Code Online (Sandbox Code Playgroud)

有什么建议?

Tre*_*ley 4

如果你使用Expression<Func<T, bool>>而不是A像这样:

public interface IRepository<T>
{
    ... // other methods
    IEnumerable<T> FindBy(Expression<Func<T, bool>> predicate);
}
Run Code Online (Sandbox Code Playgroud)

您可以使用 linq 查询类型,并在调用存储库类的代码中指定查询。

public IEnumerable<SomeClass> FindBy(Expression<Func<SomeClass, bool>> predicate)
{
    return _context.Set<SomeClass>().Where(predicate);
}
Run Code Online (Sandbox Code Playgroud)

并这样称呼它:

var results = repository.FindBy(x => x.Name == "Foo");
Run Code Online (Sandbox Code Playgroud)

鉴于它是一个通用表达式,您不必在每个存储库中实现它,您可以将它放在通用基础存储库中。

public IEnumerable<T> FindBy(Expression<Func<T, bool>> predicate)
{
    return _context.Set<T>().Where(predicate);
}
Run Code Online (Sandbox Code Playgroud)

  • 我个人喜欢这种方法,但很多人不喜欢。这意味着存储库的用户需要知道哪些表达式是 EF 安全的,哪些不是,因此这是一个有漏洞的抽象。 (2认同)