我对 EF 相当陌生,首先学习 EF 代码。我正在寻找一种知识来首先使用 EF 代码映射现有的 sql server 视图。我已经用 POCO 映射了我的视图,但出现以下错误。
当我尝试从视图中获取数据时,抛出以下错误
其他信息:支持“TestDBContext”上下文的模型 自数据库创建以来已发生变化。考虑使用代码优先 迁移以更新数据库
public class TestDBContext : DbContext
{
public TestDBContext()
: base("name=TestDBContext")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new vwCustomerConfiguration());
}
public DbSet<vwCustomer> vwCustomer { get; set; }
}
public class vwCustomerConfiguration : EntityTypeConfiguration<vwCustomer>
{
public vwCustomerConfiguration()
{
this.HasKey(t => t.CustomerID);
this.ToTable("vwCustomer");
}
}
public class vwCustomer
{
public int CustomerID { get; set; }
public string FirstName { get; set; }
}
using (var db = new TestDBContext())
{
var listMyViews = db.vwCustomer.ToList();
}
指导我在引发错误的代码中缺少什么。谢谢
当我发出添加迁移“My_vwCustomer”时,我看到添加了新的迁移代码,如下所示。似乎没有待处理的迁移。
public partial class My_vwCustomer : DbMigration
{
public override void Up()
{
CreateTable(
"dbo.vwCustomers",
c => new
{
CustomerID = c.Int(nullable: false, identity: true),
FirstName = c.String(),
})
.PrimaryKey(t => t.CustomerID);
}
public override void Down()
{
DropTable("dbo.vwCustomers");
}
}
OP的反馈:
当我使用 ADO.Net 实体模型向导生成视图时 一切正常。
您可以按照下图进行操作。
注意:我从这篇文章中选择了1到4。
为视图创建POCO类;例如
FooView
在
DbSet
类中添加 DbContext
属性
使用
FooViewConfiguration
文件为视图设置不同的名称
(在构造函数中使用 ToTable("Foo")
; )或设置特定
属性
public class FooViewConfiguration : EntityTypeConfiguration<FooView>
{
public FooViewConfiguration()
{
this.HasKey(t => t.Id);
this.ToTable("myView");
}
}
将FooViewConfiguration文件添加到modelBuilder中,例如 验证 Context 的 OnModelCreating 方法:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new FooViewConfiguration ());
}
根据上面的配置,现在你的桌子是
this.ToTable("myView");
。换句话说myView
。
这是用于检索
EF query
表上的 all the data
的 myView
。
var listMyViews = yourDbContext.myView.ToList()
您的投影可能是这样的:
var query = yourDbContext.myView
.Select(v=> new
{
ID = v.ID,
EmpName = v.EmpName,
Salary = v.Salary
}).ToList();
将视图配置为表并使用此自定义生成器来防止标记为视图的表生成迁移
public class SkipViewGenerator: CSharpMigrationCodeGenerator
{
protected override void Generate(CreateTableOperation operation, IndentedTextWriter writer)
{
if (!IsView(operation.Name))
base.Generate(operation, writer);
}
protected override void Generate(RenameTableOperation operation, IndentedTextWriter writer)
{
if (!IsView(operation.Name))
base.Generate(operation, writer);
}
protected override void Generate(MoveTableOperation operation, IndentedTextWriter writer)
{
if (!IsView(operation.Name))
base.Generate(operation, writer);
}
protected override void Generate(DropTableOperation operation, IndentedTextWriter writer)
{
if (!IsView(operation.Name))
base.Generate(operation, writer);
}
protected override void Generate(AddColumnOperation operation, IndentedTextWriter writer)
{
if (!IsView(operation.Table))
base.Generate(operation, writer);
}
protected override void Generate(DropColumnOperation operation, IndentedTextWriter writer)
{
if (!IsView(operation.Table))
base.Generate(operation, writer);
}
protected override void Generate(DropPrimaryKeyOperation operation, IndentedTextWriter writer)
{
if (!IsView(operation.Table))
base.Generate(operation, writer);
}
protected override void Generate(AlterColumnOperation operation, IndentedTextWriter writer)
{
if (!IsView(operation.Table))
base.Generate(operation, writer);
}
protected override void Generate(AddPrimaryKeyOperation operation, IndentedTextWriter writer)
{
if (!IsView(operation.Table))
base.Generate(operation, writer);
}
protected override void Generate(AlterTableOperation operation, IndentedTextWriter writer)
{
if (!IsView(operation.Name))
base.Generate(operation, writer);
}
protected override void Generate(CreateIndexOperation operation, IndentedTextWriter writer)
{
if (!IsView(operation.Name))
base.Generate(operation, writer);
}
protected override void Generate(DropIndexOperation operation, IndentedTextWriter writer)
{
if (!IsView(operation.Name))
base.Generate(operation, writer);
}
private bool IsView(string tableNameWithSchemaName)
{
var tableName = DatabaseName.Parse(tableNameWithSchemaName).Name;
var schemaName = DatabaseName.Parse(tableNameWithSchemaName).Schema;
return schemaName.Contains("View");
}
}
使用示例
internal sealed class Configuration : DbMigrationsConfiguration<MyDbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
CodeGenerator = new SkipViewGenerator();
}
protected override void Seed(MyDbContextcontext)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data.
}
}
DatabaseName.Parse
你可以从 Github sources 获取实现