简体   繁体   中英

Using Updatable Views with Entity Framework Code First

I am learning to use Entity Framework (code first). Everything was going well until I realized I need to interact with an existing updatable view. I have confirmed the view can be updated in SSMS.

There are two entities involved: AppUser (Identity User) and 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; }
}

I've used navigation properties to relate the two, thinking EF will build the join table when I run the next migration. I've read that EF treats views as read-only, so I tried to override this by creating my own EntityTypeConfiguration class:

public class FacilityViewConfiguration : EntityTypeConfiguration<FacilityView>
{
    public FacilityViewConfiguration()
    {
        this.HasKey(t => t.ID);
        this.ToTable("FacilityViews");
    }
}

The configuration is referenced in my context class inside the OnModelCreating method.

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

When I add a migration, this is the resulting Up and 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");
    }
}

It is attempting to create a new join table like I wanted, but when I run the Update-Database command, I get the following error:

Foreign key 'FK_dbo.AppUserFacilityViews_dbo.FacilityViews_FacilityViewsID' references object 'dbo.FacilityViews' which is not a user table. Could not create constraint. See previous errors.

I thought I had tricked EF into treating the view like a table, but it's obviously not buying it. I'm wondering if I missed something or maybe taking the wrong approach. Any help will be greatly appreciated. I've been stuck here for a few days.

AFAIK you can't create a constraint to/from a view (even a materialized one, exception of index).

But you can model your context without database FK. You then have to handle the integrity at context or application level

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM