我正在尝试将SQL视图映射到EF 5.0 Code First w / Migrations中的实体,以便在页面上显示一些基本信息,而无需为该信息查询多个表(目前需要大约20秒才能加载)。 不好。)。我听说有可能这样做,但我无法弄清楚或在网上找到正确的方法。
编辑:要更深入地了解我对此问题的解决方案,请阅读有关该主题的this blog post。
这是我的观点:
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.
我做错了什么?有没有办法让我做到这一点,或者我应该做其他事情呢?
答案 0 :(得分:14)
您已指定ClientStatisticsView
实体应映射到名为“ClientStatistics”的表。因此,实体框架将生成包含创建该表的指令的迁移。但是您已经在数据库中独立创建了该视图,以防止出现错误,应该从CreateTable
迁移中删除Up
指令。
我认为更好的方法是通过运行这样的sql在迁移中创建视图:
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/
答案 1 :(得分:0)
将ToTable属性添加到您的实体,并将其作为DbSet包含在您的上下文中。
[ToTable("ClientStatics")]
public class ClientStaticsView{}
public class DataContext : DbContext
{
public DbSet<ClientStaticsView> ClientStatics { get; set; }
}
或者,如果您不想将DbSet添加到上下文中,请为ClientStatisView创建EntityTypeConfiguration,并使用流畅的api而不是属性包含ToTable属性。然后,您可以在上下文的OnModelCreating:
中将实体添加到您的上下文中public class ClientStaticsViewConfiguration : EntityTypeConfiguration<ClientStaticsView>
{
public ClientStatusViewConfiguration
{
ToTable("ClientStatics");
}
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new ClientStatisViewConfiguration());
}