背景
有几种情况下,应用程序可能需要通过组合两个或多个表(有时甚至超过7-8个表)来显示数据。在这种情况下,使用实体框架可能会导致性能降低,因为我们需要通过从表中选择数据进行处理,然后从其他表中运行一些循环。
但是,数据库本身有许多特性来处理这些情况下的性能,例如存储过程或创建最受推荐的视图,从而获得更好的性能。
另一方面,实体框架作为一种开放源码的ORM框架,由于其众多的优点而在.net开发人员中得到了广泛的应用,它不仅可以加快编码速度,而且可以方便地直接用代码控制数据库。
在本文中,我将展示如何利用实体框架中数据库视图的优势,并通过创建视图和在实体框架中处理这些视图来克服复杂的连接/查询问题。
数据库视图
视图被视为一个基于其他表的SQL语句形成的虚拟表。这可以看作是一个真正的表;但是,我们不能执行诸如delete或update之类的命令。简单地说,它包含从表中提取数据的查询。我们通常使用WHERE、FUNCTION并且或JOIN到表来形成一个视图。
我们创建视图是为了简化查询:我们可以编写复杂的查询来从各种表中选择数据,而不是每次都编写那些复杂的查询;我们创建视图是为了像简单表一样使用它。其他优点还有性能改进、数据安全性和易用性。
我们可以通过两种方式创建视图(mssqlserver):SQL脚本和查询设计器。
SQL Script Syntax
CREATE VIEW view_name AS
SELECT column1, column2.....
FROM table_name
WHERE [condition];
我们可以使用where、function、join等编写复杂的查询,甚至可以使用union。
Query Designer
我们可以利用查询设计器的优势,如图所示,
我们可以添加表,添加关系(基于自动关系的primarykey foreignkey),修改别名,如上图所示。有手动修改查询和检查结果的选项。
在实体框架中处理视图
我们可以利用实体框架数据库中的视图,首先考虑模型。然而,在实体框架代码优先的方法中,我们需要做一些技巧。如果我们创建视图模型,那么它将在add migration和database update命令中创建这些视图的表。
技巧
在实体框架中,我们可以用两种方式处理视图。
方案1
手动创建一个组合数据库中多个表的视图,然后为该视图添加一个实体。最后,我们可以在modelcreating entity builder上为实体添加ignore,如下所示。
样本代码
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
if (IsMigration)
modelBuilder.Ignore<ViewEntityName>();
...
}
利用上述技巧,我们可以简单地利用实体模型的优势,而忽略代码优先方法中的迁移和数据库更新。
方案2
或者,可以创建扩展或属性来处理数据库中的视图。在这个选项中,我们可以在数据库中手动创建一个视图,然后添加一个扩展或属性。
样本代码
//Property
class DBContext
{
public IQueryable<YourView> YourView
{
get
{
return this.Database.SqlQuery<YourView>("select * from dbo.ViewName");
}
}
}
扩展
static class DbContextExtensions
{
public static IQueryable<ViewNameModel>(this DbContext context)
{
return context.Database.SqlQuery<ViewNameModel>("select * from dbo.ViewName");
}
}
我们可以构建数据库上下文扩展来处理视图,并在我们的解决方案中使用代码优先的方法。
还有一些其他的替代方法,但是,我更喜欢这些选项,因为它们很容易实现。
结论
在本文中,我们学习了如何以代码优先的方式在实体框架中实现数据库视图,并利用这些视图处理复杂的查询,克服实体框架中复杂的连接/查询问题。在性能、易用性、数据安全性以及最重要的查询简单性方面,数据库视图对于复杂查询非常有效。