首先将可更新视图与实体框架代码一起使用

Posted

技术标签:

【中文标题】首先将可更新视图与实体框架代码一起使用【英文标题】:Using Updatable Views with Entity Framework Code First 【发布时间】:2015-07-06 14:59:17 【问题描述】:

我正在学习使用实体框架(代码优先)。一切都很顺利,直到我意识到我需要与现有的可更新视图进行交互。我已经确认可以在 SSMS 中更新视图。

涉及两个实体:AppUser(身份用户)和 FacilityView。

public class AppUser : IdentityUser
        
    // additional props
    public virtual ICollection<FacilityView> Facilities  get; set; 


public class FacilityView

    [HiddenInput(DisplayValue=false)]
    public int ID  get; set; 
    public string Name  get; set; 
    public string County  get; set; 
    public string WebSiteURL  get; set; 
    public bool IsActive  get; set; 

    public virtual ICollection<AppUser> Users  get; set; 

我使用导航属性将两者关联起来,认为 EF 将在我运行下一次迁移时构建连接表。我读过 EF 将视图视为只读,因此我尝试通过创建自己的 EntityTypeConfiguration 类来覆盖它:

public class FacilityViewConfiguration : EntityTypeConfiguration<FacilityView>

    public FacilityViewConfiguration()
    
        this.HasKey(t => t.ID);
        this.ToTable("FacilityViews");
    

配置在 OnModelCreating 方法内的上下文类中被引用。

public class AppIdentityDbContext : IdentityDbContext<AppUser>

    public AppIdentityDbContext() : base("DbConn")  

    public DbSet<Facility> Facilities  get; set; 
    public DbSet<FacilityView> FacilityDetails  get; set;         

    static AppIdentityDbContext()
    
        Database.SetInitializer<AppIdentityDbContext>(new DbConnInit());
    

    public static AppIdentityDbContext Create()
    
        return new AppIdentityDbContext();
    

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    

        base.OnModelCreating(modelBuilder);

        // TRYING TO TRICK EF HERE
        modelBuilder.Configurations.Add(new FacilityViewConfiguration());           
    
  

当我添加迁移时,这就是结果 Up 和 Down:

public partial class UserFacilityJoinTable : DbMigration

    public override void Up()
    
        CreateTable(
            "dbo.AppUserFacilityViews",
            c => new
                
                    AppUser_ID = c.String(nullable: false, maxLength: 128),
                    FacilityViewsID = c.Int(nullable: false),
                )
            .PrimaryKey(t => new  t.AppUser_ID, t.FacilityViewsID )
            .ForeignKey("dbo.AspNetUsers", t => t.AppUser_ID, cascadeDelete: true)
            .ForeignKey("dbo.FacilityViews", t => t.FacilityViewsID, cascadeDelete: true)
            .Index(t => t.AppUser_ID)
            .Index(t => t.FacilityViewsID);

    

    public override void Down()
    
        DropForeignKey("dbo.AppUserFacilityViews", "FacilityViewsID", "dbo.FacilityViews");
        DropForeignKey("dbo.AppUserFacilityViews", "AppUser_ID", "dbo.AspNetUsers");
        DropIndex("dbo.AppUserFacilityViews", new[]  "FacilityViewsID" );
        DropIndex("dbo.AppUserFacilityViews", new[]  "AppUser_ID" );
        DropTable("dbo.AppUserFacilityViews");
    

它正在尝试像我想要的那样创建一个新的连接表,但是当我运行 Update-Database 命令时,我收到以下错误:

外键“FK_dbo.AppUserFacilityViews_dbo.FacilityViews_FacilityViewsID”引用不是用户表的对象“dbo.FacilityViews”。 无法创建约束。查看以前的错误。

我以为我欺骗了 EF 将视图视为一张桌子,但它显然不买它。我想知道我是否错过了什么或者采取了错误的方法。任何帮助将不胜感激。我被困在这里好几天了。

【问题讨论】:

AFAIK 您无法创建与视图之间的约束(即使是物化视图,索引除外)。但是您可以在没有数据库 FK 的情况下为您的上下文建模。然后,您必须在上下文或应用程序级别处理完整性 @tschmit007:您的评论就是答案。请照此张贴。当您发表这样的评论时,它会阻止其他人回答,因为您基本上已经回答了。然而,现在,这个问题将无限期地“悬而未决”。 @tschmit007 - 我想你已经搞定了。我注释掉了 db 视图的 FK 约束定义,它允许我更新数据库。我正在考虑回滚迁移并更改 FK 约束以指向 Facility 基表。我很想知道你的想法。此外,正如 Chris Pratt 所指出的,请发布您的贡献作为答案,以防万一。我想在应得的地方给予信任并结束问题。谢谢大家! 【参考方案1】:

AFAIK 您无法创建与视图之间的约束(即使是物化视图,索引除外)。

但是您可以在没有数据库 FK 的情况下为您的上下文建模。然后,您必须在上下文或应用程序级别处理完整性

【讨论】:

以上是关于首先将可更新视图与实体框架代码一起使用的主要内容,如果未能解决你的问题,请参考以下文章

如何首先使用实体​​框架代码更新一行?

实体框架6代码首先用oracle更新实体

AWS Lambda:将可执行文件与 python 一起使用

无法获取要更新实体框架中导航属性的关系

如何将可扩展列表视图的选定子视图数据从片段发送到父活动?

在实体框架中更新具有所需属性的实体