如何在代码第一实体框架中使用视图

Sag*_*gar 81 .net database entity-framework view code-first

我如何首先在实体框架代码中使用数据库视图,

Dan*_*sco 85

如果像我一样,您只对来自其他数据库的映射实体(在我的情况下是一个erp)感兴趣,将它们与特定于您的应用程序的实体相关联,那么您可以在使用表时使用视图(将视图映射到一样的方法!).显然,如果您尝试更新这些实体,如果视图不可更新,您将收到异常.该过程与普通(基于表)实体的情况相同:

  1. 为视图创建一个POCO类; 例如FooView
  2. 在DbContext类中添加DbSet属性
  3. 使用FooViewConfiguration文件为视图设置不同的名称(使用ToTable("Foo");在构造函数中)或设置特定属性

    public class FooViewConfiguration : EntityTypeConfiguration<FooView>      
    {
        public FooViewConfiguration()
        {
            this.HasKey(t => t.Id);
            this.ToTable("myView");
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  4. 将FooViewConfiguration文件添加到modelBuilder,例如,使上下文的OnModelCreating方法失效:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new FooViewConfiguration ());
    }
    
    Run Code Online (Sandbox Code Playgroud)

  • +1表示不假设"Code First"==自动生成数据库 (55认同)
  • 它只是我,还是每个人都得到了迁移创建的空表?有没有办法避免这种情况? (18认同)
  • 只是在这里确定,这个解决方案是否需要我们事先在外部创建SQL数据库上的View?是否可以在代码中定义视图并通过Add-Migration/Update-Database命令将其填充到数据库中? (4认同)
  • 一些东西.1.这个答案没有提到您必须使用SQL手动创建视图,这可以使用迁移来完成.2.如果类名与视图名称匹配,则不必配置视图名称.3.你可以像这样使用DataAnnotations:`[Table("myView")]`,这比使用创建`EntityTypeConfiguration`简单得多. (4认同)
  • @DaveJellison你是否愿意详细说明,或提供一个关于添加视图的链接作为IDatabaseInitializer的一部分 (3认同)
  • 你的意思是只为视图创建一个类似于其他实体的类,例如名为`FooView`并在我的DbContext类中添加一个`DbSet <FooView>`属性,实体框架知道将它映射到视图(假设我们有一个视图名为`dbo.Foo`)?? (2认同)
  • 是的,您可以使用FooViewConfiguration文件为视图设置不同的名称(使用ToTable("Foo");在构造函数中)或设置特定属性.就像你使用表而不是视图一样. (2认同)

Al *_*azi 15

这可能是一个更新,但要使用EF代码的视图首先只需将[Table("NameOfView")]添加到类的顶部,所有这些都应该正常工作,而不必经历其他人正在经历的所有箍.此外,您还必须将其中一列报告为[key]列.下面是我的示例代码来实现它.

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace SomeProject.Data
{
    [Table("SomeView")]
    public class SomeView
    {
        [Key]
        public int NameID { get; set; }
        public string Name { get; set; }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是上下文的样子

using System.Data.Entity;

namespace SomeProject.Data
{
    public class DatabaseContext : DbContext
    {
        public DbSet<SomeView> SomeViews { get; set; }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 其实不,不是。我尝试了接受的答案,但没有成功,但对我来说效果不佳。但是后来我使用了迁移,所以这可能会影响事情。我发现我必须先进行迁移,然后添加我的视图类,因为它已经存在于数据库中。如果数据库中已有表,我们将以完全相同的方式处理它。由于视图是“虚拟表”,因此实体框架中的表语法仍然有效。 (3认同)
  • 这与接受的答案相同,除了它使用 DataAnnotations 而接受的答案使用 EF Fluid API。 (2认同)

小智 10

如果你想要的只是一堆非规范化的对象,那么你可能只是IQueryable<TDenormolized>在你的DbContext类中创建了一个公共的get-only 属性.

get您返回Linq结果时,将去正规化的值投影到您的非规范化对象中.这可能比编写DB View更好,因为您正在编程,您不仅仅使用select语句.它也是编译时类型安全的.

请注意不要触发ToList()调用之类的枚举,否则会破坏延迟查询,最终可能会从数据库中获取一百万条记录并在应用程序服务器上过滤它们.

我不知道这是不是正确的方法,但我尝试过,它对我有用.

  • 我想使用视图的原因之一是EF生成的SQL并不总是"很好" - 我们的模型中有一些继承层次结构(发现陷阱太晚了......)并且使用视图允许我们手动创建SQL.只是为什么一个观点更可取的对立点 (5认同)
  • 不这样做的其他原因可能是使用了递归公用表表达式,这在LINQ中不可用。否则,这对于较简单的方案是一个很好的建议。 (2认同)
  • 如果您想利用*索引*视图的优势,那么使用属性而不是视图不是一个选择。 (2认同)