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

时间:2013-12-31 20:18:57

标签: c# entity-framework ef-code-first entity-framework-5 ef-migrations

我正在尝试将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.

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

2 个答案:

答案 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());
}