将数据库视图映射到EF 5.0 Code First w / Migrations

我试图在EF 5.0 Code First w / Migrations中将SQL视图映射到实体上,以便在页面上显示一些基本信息,而无需查询多个表中的信息(加载时间大约需要20秒,而不是很好。 )。 我听说有可能这样做,但我一直无法find或find一种正确的方式。

编辑:为了更深入的看看我对这个问题的解决scheme,请阅读这个主题的博客文章 。

这是我的观点:

CREATE VIEW [dbo].[ClientStatistics] AS SELECT ROW_NUMBER() OVER (Order By c.ID) as Row, c.LegacyID, c.ID, c.ClientName, slc.AccountManager, slc.Network, (SELECT MAX(CreatedDate) AS Expr1 FROM dbo.DataPeriods WHERE (ClientID = c.ID)) AS LastDataReceived, (SELECT MAX(ApprovedDate) AS Expr1 FROM dbo.DataPeriods AS DataPeriods_2 WHERE (ClientID = c.ID)) AS LastApproved, (SELECT MAX(ReportProcessedDate) AS Expr1 FROM dbo.DataPeriods AS DataPeriods_1 WHERE (ClientID = c.ID)) AS LastReportProcesssed FROM dbo.Clients AS c INNER JOIN dbo.SLClients AS slc ON c.ID = slc.ClientID 

这是实体:

 public class ClientStatisticsView { [Key] public int Row { get; set; } public int LegacyID { get; set; } public int ClientID { get; set; } public string ClientName { get; set; } public string AccountManager { get; set; } public string Network { get; set; } public DateTime LastDataReceived { get; set; } public DateTime LastApproved { get; set; } public DateTime LastReportProcessed { get; set; } } 

最后我在DbContext映射:

 protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); modelBuilder.Entity<ClientStatisticsView>().ToTable("ClientStatistics"); base.OnModelCreating(modelBuilder); } 

所有这些给我以下错误:

There is already an object named 'ClientStatistics' in the database.

我究竟做错了什么? 有没有办法让我做到这一点,或者我应该做一些其他的事情吗?

您已指定将ClientStatisticsView实体映射到名为“ClientStatistics”的表。 所以entity framework将生成包含创build该表的指令的迁移。 但是您已经在数据库中独立创build了这个视图,为了防止出现错误,您应该从Up迁移中删除CreateTable指令。

我认为更好的方法是通过像这样运行sql来在迁移中创build视图:

 public override void Up() { Sql("EXEC ('CREATE View [dbo].[ClientStatistics] AS --etc" } public override void Down() { Sql(@"IF EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'dbo.ClientStatistics')) DROP VIEW dbo.ClientStatistics)") } 

这样,您的视图和表格就可以在一个地方指定,并且可以安全地上下移动

参考

http://elegantcode.com/2012/04/12/entity-framework-migrations-tips/

我实际上正在使用entity framework“Code First”和视图,我这样做的方式是这样的:

1)创build一个class级

 [Table("view_name_on_database")] public class ViewClassName { // View columns mapping public int Id {get; set;} public string Name {get; set;} // And a few more... } 

2)将该类添加到上下文中

 public class ContextName : DbContext { // Tables public DbSet<SomeTableClassHere> ATable { get; set; } // And other tables... // Views public DbSet<ViewClassName> ViewContextName { get; set; } // This lines help me during "update-database" command protected override void OnModelCreating(DbModelBuilder modelBuilder) { // Remove comments before "update-database" command and // comment this line again after "update-database", otherwise // you will not be able to query the view from the context. // Ignore the creation of a table named "view_name_on_database" modelBuilder.Ignore<ViewClassName>(); } } 

有点晚,但我希望这有助于某人。

如果在“update-database”期间有一种方法可以忽略创build一个名为view的表,并且在这之后不会忽略,那将是非常好的。

将ToTable属性添加到您的实体,并将其作为DbSet包含在您的上下文中。

 [ToTable("ClientStatics")] public class ClientStaticsView{} public class DataContext : DbContext { public DbSet<ClientStaticsView> ClientStatics { get; set; } } 

或者,如果您不想将DbSet添加到上下文中,请为您的ClientStatisView创build一个EntityTypeConfiguration,并将ToTable属性包含在stream畅的api中,而不是属性中。 然后,您可以将该实体添加到上下文的OnModelCreating中的上下文中:

 public class ClientStaticsViewConfiguration : EntityTypeConfiguration<ClientStaticsView> { public ClientStatusViewConfiguration { ToTable("ClientStatics"); } } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.Add(new ClientStatisViewConfiguration()); }