代码解开 - T 的查询做什么

Code disentangle - what does query of T do

我们有三个组件:WinForm-Rich-Client,使用 WebApi 的 IIS-Webserver,entity framework 用于大多数数据库查询。

我得到了一个代码库,但我迷路了。我不明白一些 classes Student 是使用 TEntityType 动态传递的。我读过的 msdn 文档 当您静态不知道 T 的类型时,可以使用这种方法。

我试图理解下面的行,它们的作用以及所有接口和抽象 classes 之间的关系是否有任何好处

var students = DbEntityAccess.Query<Students>().ToList();

// the query member from Our.DAL.Interfaces.IEntityAccess 
IQueryable<TEntTyp> 
              Query<TEntTyp>(Expression<Func<TEntTyp, bool>> query)
                  where TEntTyp: class;

DBEntityAccesss

定义 (F12) 和 DBEntityAccesss 的实现都导致

namespace Our.Webservice.Controllers
{
   public abstract class SessionBaseController : ApiController
   {
      protected IEntityAccess DbEntityAccess { get; private set; }
   }
}

旁注:Visual Studio 建议将 DbEntityAccess 重命名为 GetDbEntityAccess

IEntityAccess

定义(F12)和实现(STRG+F12)IEntityAccess这些是

// Definition of SessionBaseController.IEntityAccess
namespace Our.DAL.Interfaces
{
  public interface IEntityAccess
  {
    IQueryable<TEntTyp> 
       Query<TEntTyp>(Expression<Func<TEntTyp, bool>> query)
            where TEntTyp: class;
  }
}


// Implementation of SessionBaseController.IEntityAccess
namespace Our.DAL.Implementations
{
   public class TpdEntities : DbAccess, IEntityAccess
   {
     // TEntityType shortened to TEntTyp 
     public IQueryable<TEntTyp> Query<TEntTyp>() where TEntTyp: class
     {
       return Set<TEntTyp>();
     }
   }
}

Our.DAL.Implementations.TpdEntities

class Our.DAL.Implementations.TpdEntities 正在实现接口 Our.DAL.Interfaces.IEntityAccess (见上文)并继承自 DbAccess ,后者是继承自 [ 的抽象 class =25=]

Our.DAL.Implementations.DbAccess

不清楚 DbAccess 的贡献。

namespace Our.DAL.Implementations
{
  public abstract class DbAccess : DbContext
  {
      // Constructor
      protected DbAccess()
          : base("name=TPDEntities")
      {
          Configuration.AutoDetectChangesEnabled = false;
      }
  }
}

问题

第一部分是如何连接的

感谢和问候

所以 IEntityAccess 的实现应该不起作用,因为它缺少参数 Expression<Func<TEntTyp, bool>> query 它应该看起来像:

namespace Our.DAL.Implementations
{
   public class TpdEntities : DbAccess, IEntityAccess
   {
     // TEntityType shortened to TEntTyp 
     public IQueryable<TEntTyp> Query<TEntTyp>(Expression<Func<TEntTyp, bool>> query) 
     where TEntTyp: class
     {
       return Set<TEntTyp>().Where(query);
     }
   }
}

正如现在所写,与直接访问 DbAccess 没有区别class。如果您查看 DbAccess,它会继承 DbContext(Entity Framework) 并保存集合。

What does query do, how and when does EF come into play var students = DbEntityAccess.Query().ToList();

因此,DbEntityAccess 是一个接口,但具有 TpdEntities 的实现。假设这是设置的,与 DbAccess.Students.

相同

What does the part Query<TEntTyp>(Expression<Func<TEntTyp, bool>> query) where TEntTyp: class; do?

这是有趣的部分。您可以使用 Predicate 进一步过滤集合。例如,您只需要当前注册的学生。如果你用 DbAccess 试试这个,它看起来像:

var registeredStudents = DbAccess.Students.Where(student => student.IsRegistered);

查询方法做同样的事情:

var registeredStudents = DbEntityAccess.Query(student => student.IsRegistered);    

student => student.IsRegistered 是一个谓词 Func<Student, bool>,如果满足某些条件,return 就是学生。

为什么你想要所有这些抽象?

为了将来的可扩展性。让我们想象一下,这个控制器只关心当前注册的学生,永远不需要过去的学生。然后可以将 TpdEntities 切换为

namespace Our.DAL.Implementations
{
   public class CurrentStudentsRepository : DbAccess, IEntityAccess
   {
     // TEntityType shortened to TEntTyp 
     public IQueryable<Student> Query<Student>(Expression<Func<Student, bool>> query) 
     where Student: class
     {
       return Set<Student>().Where(student => student.IsRegistered).Where(query);
     }
   }
}

因为这个 returns IQueryable 你可以在要求数据库获取数据之前进一步过滤集合。

var students = DbEntityAccess.Query(student => student.FirstName == "Jim");

将 return 所有当前注册的学生以非常易读的方式命名为 Jim。