【问题标题】:Code disentangle - what does query of T do代码解开 - 查询 T 做什么
【发布时间】:2017-06-01 00:57:05
【问题描述】:

我们有三个组件:WinForm-Rich-Client,使用 WebApi 的 IIS-Webserver,大多数数据库查询的实体框架。

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

我正在尝试理解以下几行,它们的作用以及所有接口和抽象类之间的关系是否有任何好处

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

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

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

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

IEntityAccess

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

// 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

Our.DAL.Implementations.TpdEntities 类实现了接口Our.DAL.Interfaces.IEntityAccess(见上文)并继承自DbAccess,后者是继承自System.Data.Entity.DbContext 的抽象类

Our.DAL.Implementations.DbAccess

尚不清楚DbAccess 的贡献。

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

问题

第一部分是如何连接的

  • 查询有什么作用,EF 如何以及何时发挥作用var students = DbEntityAccess.Query&lt;Students&gt;().ToList();

  • Query<TEntTyp>(Expression<Func<TEntTyp, bool>> query) where TEntTyp: class; 的作用是什么?

  • 对我来说,不清楚 Query 的作用是什么?
  • 如何查询传递过来的TTEntTyp?
  • Expression&lt;Func&lt;TEntTyp, bool&gt;&gt; query 是什么意思?

感谢和问候

【问题讨论】:

  • 你真的需要了解所有这些来维护项目吗?
  • 是的,我想了解代码的作用。我们正面临性能问题。在我们的数据库跟踪中,我们发现某些非常慢的数据库查询 - 选择所有列而没有任何条件(谓词)。

标签: c# entity-framework linq architecture abstraction


【解决方案1】:

所以 IEntityAccess 的实现不应该工作,因为它缺少参数Expression&lt;Func&lt;TEntTyp, bool&gt;&gt; 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 类没有区别。如果您查看 DbAccess,它会继承 DbContext(Entity Framework) 并保存集合。

查询的作用是什么,EF 如何以及何时发挥作用 var students = DbEntityAccess.Query().ToList();

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

Query&lt;TEntTyp&gt;(Expression&lt;Func&lt;TEntTyp, bool&gt;&gt; query) where TEntTyp: class; 部分是做什么的?

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

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

Query 方法做同样的事情:

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

student =&gt; student.IsRegistered 是一个谓词Func&lt;Student, bool&gt;,如果学生满足某些条件,则返回该学生。

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

为了将来的可扩展性。让我们想象一下,这个控制器只关心当前注册的学生,永远不会需要过去的学生。然后可以将 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);
     }
   }
}

因为这会返回 IQueryable,所以您可以在要求数据库获取数据之前进一步过滤集合。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多