How can I use database Views in a scaffolded DbContext with Entity Framework Core 1.0 (EF7)

后端 未结 2 1127
攒了一身酷
攒了一身酷 2021-01-02 16:15

Unfortunately Entity Framework Core 1.0 (formerly Entity Framework 7) does not yet support Views, and I\'m trying to \'fake\' it using a table.

Howe

2条回答
  •  清酒与你
    2021-01-02 16:31

    Here's what I came up with :

    I create a partial class that inherits from the DbContext and then add any new logic to it by overriding the OnModelCreating method.

    Eventually the EF scaffolder should (I hope) be able to create views for me, so in the interim I'm calling the class MyStoreContext_WithViews so I can do a search and replace at some point to update it.

    The database view in this example is called RepeatOrderSummaryView.

    I had to add all the columns manually to my view class here (since the scaffolder doesn't support it). That's fine for now.

    There is no key on the View, but EF requires a key so I just create a fake one using one of the columns.

    namespace MyStore.EF.Model
    {
        public partial class MyStoreContext_WithViews : MyStoreContext
        {    
            protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
                base.OnModelCreating(modelBuilder);
    
                modelBuilder.Entity(entity =>
                {
                    entity.HasKey(e => new { e.FirstOrder_Date })
                        .HasName("PK_FAKEKEY");
                });
            }
    
            public virtual DbSet RepeatOrderSummaryView { get; set; }    
        }
    
        [Table("RepeatOrderSummaryView")]
        public partial class RepeatOrderSummaryView
        {
            public DateTime OrderDate { get; set; }
            public bool HasShipped { get; set; }
        }
    }
    

    I was then able to successfully run this query against the View:

     RRStoreContext_WithViews ctx = new RRStoreContext_WithViews();
     var data = ctx.RepeatOrderSummaryView.Where(x => x.HasShipped == true);
    

    Since this class just inherits from my generated DbContext (MyStoreContext) I can of course use all the rest of the tables that were scaffolded.

    Not tested on updateable views - of course if you try this you'll need a real PK defined.


    Because you aren't returning 'real' entities, or necessarily items with a real key defined you should use .AsNoTracking(). I found fewer results in my result set than I expected and it was because it was doing a key match and thinking it already had the object in memory.

    Be sure to test carefully to ensure the number of results is as expected - or you're going to run into big problems.

    What difference does .AsNoTracking() make?

提交回复
热议问题