不幸的是实体框架核心1.0 (以前的实体框架7)尚不支持视图,我试图假冒'它使用表格。
然而,脚手架dotnet dbcontext ef scaffold
命令当前没有识别或生成视图,我想要一个允许查询视图和更新表的DbContext。有没有办法做到这一点?
这是我用来搭建DbContext的命令:
dotnet ef dbcontext scaffold -c MyStoreContext -o Model "Data Source=(local);Initial Catalog=DBNAME;Integrated Security=True" Microsoft.EntityFrameworkCore.SqlServer --force
(这会将我的所有模型类放在Model
目录中,并强制它们被覆盖。)
注意:我实际想要使用View的原因是GROUP BY逻辑,在EF Core 1.0中不支持
答案 0 :(得分:5)
对我来说,我的观点是在不同的架构中,所以我不得不改变模型类的属性:
using System.ComponentModel.DataAnnotations.Schema;
namespace API.DataAccess
{
[Table("MyViewName", Schema = "SomeSchema")]
public class MyViewName
{
//props
}
}
为完整起见,实体代码:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MyViewName>(entity =>
{
entity.HasKey(e => new { e.SomeColumn }).HasName("PK_FAKEKEY");
entity.Property(e => e.SomeColumn ).IsRequired();
entity.Property(e => e.SomeColumn2 );
entity.Property(e => e.SomeColumn3 );
});
}
答案 1 :(得分:1)
以下是我提出的建议:
我从DbContext
创建继承的部分类,然后通过覆盖OnModelCreating
方法向其添加任何新逻辑。
最终EF脚手架应该(我希望)能够为我创建视图,所以在此期间我正在调用类MyStoreContext_WithViews
,所以我可以在某个时候进行搜索和替换以更新它。
此示例中的数据库视图称为RepeatOrderSummaryView
。
我必须在这里手动将所有列添加到我的视图类中(因为脚手架不支持它)。那现在很好。
View上没有键,但EF需要一个键,所以我只使用其中一列创建一个伪造的键。
namespace MyStore.EF.Model
{
public partial class MyStoreContext_WithViews : MyStoreContext
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<RepeatOrderSummaryView>(entity =>
{
entity.HasKey(e => new { e.FirstOrder_Date })
.HasName("PK_FAKEKEY");
});
}
public virtual DbSet<RepeatOrderSummaryView> RepeatOrderSummaryView { get; set; }
}
[Table("RepeatOrderSummaryView")]
public partial class RepeatOrderSummaryView
{
public DateTime OrderDate { get; set; }
public bool HasShipped { get; set; }
}
}
然后我能够针对View成功运行此查询:
RRStoreContext_WithViews ctx = new RRStoreContext_WithViews();
var data = ctx.RepeatOrderSummaryView.Where(x => x.HasShipped == true);
由于这个类只是继承自我生成的DbContext(MyStoreContext
),我当然可以使用所有其他脚手架的表。
未在可更新视图上进行测试 - 当然,如果您尝试此操作,则需要定义真正的PK。
因为您没有返回“真实”实体,或者必须定义具有真实密钥的项目,所以您应该使用.AsNoTracking()
。我发现结果集中的结果比我预期的要少,这是因为它正在进行一次关键匹配并认为它已经在内存中有了对象。
请务必仔细测试以确保结果数量符合预期 - 否则您将遇到大问题。