EntityFramework尝试获取不存在的列 [英] EntityFramework is trying to fetch non-existing column
问题描述
在我的情况下,我有两个表与单对多的关系:
T_Blog
- Id
- FeaturedPost
T_Post
- Id
- BlogId
我定义了实体数据模型
public class T_Blog
{
[Key]
public int Id {get; set;}
public诠释?特征PostId {get; set;}
[ForeignKey(FeaturedPostId)]
public virtual T_Post FeaturedPost {get; set;}
public virtual ICollection< T_Post>帖子{get; set;}
}
public class T_Post
{
[Key]
public int Id {get; set;}
[必需]
public int BlogId {get; set;}
[ForeignKey(BlogId)]
public T_Blog Blog {get; set;}
)
这个元数据被定义为EF正在尝试获取 T_Blog_Id
列每次我试图执行db.T_Post.Where(...)ToList();
我知道,只要我的T_Blog有两个引用T_Post,然后EF尝试获取两个Ids。
ps:是的,我知道这种类型的数据模型不是最优的,但是在我的情况下(至少在现在)需要这种类型的非规范化。 >
如何正确定义第二个关系,所以EF知道要获取什么?
您应该使用FluentAPI而不是注释来避免这种映射失败。
以下是您的模型示例
public class BlogContext: DbContext
{
public BlogContext()
:base(name = BlogContext)
{
}
protected override void OnModelCreating DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
var blog = modelBuilder.Entity< T_Blog>();
blog.HasKey(e => e.Id);
blog.HasOptional(e => e.FeaturedPost)
.WithMany()
.HasForeignKey(e => e.FeaturedPostId)
.WillCascadeOnDelete(false);
var post = modelBuilder.Entity< T_Post>();
post.HasKey(e => e.Id);
post.HasRequired(e => e.Blog)
.WithMany(e => e.Posts)
.HasForeignKey(e => e.BlogId)
.WillCascadeOnDelete(true);
}
public virtual DbSet< T_Blog>博客{get;组; }
public virtual DbSet< T_Post>帖子{get;组; }
}
public class T_Blog
{
public int Id {get;组; }
public virtual ICollection< T_Post>帖子{get;组; }
public int? FeaturedPostId {get;组; }
public virtual T_Post FeaturedPost {get;组; }
}
public class T_Post
{
public int Id {get;组; }
public int? BlogId {get;组; }
public virtual T_Blog Blog {get;组;
}
和自动生成迁移
public partial class InitialCreate:DbMigration
{
public override void Up()
{
CreateTable(
dbo.T_Blog,
c => new
{
Id = c.Int(nullable:false,identity:true),
FeaturedPostId = c.Int(),
})
.PrimaryKey(t => t.Id)
.ForeignKey(dbo.T_Post,t => t.FeaturedPostId)
.Index(t = t.FeaturedPostId);
CreateTable(
dbo.T_Post,
c => new
{
Id = c.Int(nullable:false,identity:true ),
BlogId = c.Int(nullable:false),
})
.PrimaryKey(t => t.Id)
.ForeignKey(dbo.T_Blog ,t => t.BlogId,cascadeDelete:true)
.Index(t => t.BlogId);
}
public override void Down()
{
DropForeignKey(dbo.T_Blog,FeaturedPostId,dbo.T_Post) ;
DropForeignKey(dbo.T_Post,BlogId,dbo.T_Blog);
DropIndex(dbo.T_Post,new [] {BlogId});
DropIndex(dbo.T_Blog,new [] {FeaturedPostId});
DropTable(dbo.T_Post);
DropTable(dbo.T_Blog);
}
}
EntityFramework is trying to fetch non-existing column and foreign key attribute doesn't help.
In my case, I have two tables with single to multiple relationships:
T_Blog
- Id
- FeaturedPost
T_Post
- Id
- BlogId
and I defined entity data model
public class T_Blog
{
[Key]
public int Id {get;set;}
public int? FeaturedPostId {get;set;}
[ForeignKey("FeaturedPostId")]
public virtual T_Post FeaturedPost {get;set;}
public virtual ICollection<T_Post> Posts {get;set;}
}
public class T_Post
{
[Key]
public int Id {get;set;}
[Required]
public int BlogId {get;set;}
[ForeignKey("BlogId")]
public T_Blog Blog {get;set;}
}
And having this metadata defined EF is trying to fetch T_Blog_Id
column everytime I'm trying to execute db.T_Post.Where(...).ToList();
I got it that as long as my T_Blog has two references to T_Post, then EF is trying to fetch both Ids.
ps: yeah, I know this type of data model is not optimal but this type of denormalization is needed in my case (at least as of now).
How to properly define the second relationship so EF knows what to fetch?
You should use the FluentAPI instead of annotations to avoid that kind of mapping fails.
Here is a sample for your model
public class BlogContext : DbContext
{
public BlogContext()
: base( "name=BlogContext" )
{
}
protected override void OnModelCreating( DbModelBuilder modelBuilder )
{
base.OnModelCreating( modelBuilder );
var blog = modelBuilder.Entity<T_Blog>();
blog.HasKey( e => e.Id );
blog.HasOptional( e => e.FeaturedPost )
.WithMany()
.HasForeignKey( e => e.FeaturedPostId )
.WillCascadeOnDelete( false );
var post = modelBuilder.Entity<T_Post>();
post.HasKey( e => e.Id );
post.HasRequired( e => e.Blog )
.WithMany( e => e.Posts )
.HasForeignKey( e => e.BlogId )
.WillCascadeOnDelete( true );
}
public virtual DbSet<T_Blog> Blogs { get; set; }
public virtual DbSet<T_Post> Posts { get; set; }
}
public class T_Blog
{
public int Id { get; set; }
public virtual ICollection<T_Post> Posts { get; set; }
public int? FeaturedPostId { get; set; }
public virtual T_Post FeaturedPost { get; set; }
}
public class T_Post
{
public int Id { get; set; }
public int? BlogId { get; set; }
public virtual T_Blog Blog { get; set; }
}
and the autogenerated migration
public partial class InitialCreate : DbMigration
{
public override void Up()
{
CreateTable(
"dbo.T_Blog",
c => new
{
Id = c.Int(nullable: false, identity: true),
FeaturedPostId = c.Int(),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.T_Post", t => t.FeaturedPostId)
.Index(t => t.FeaturedPostId);
CreateTable(
"dbo.T_Post",
c => new
{
Id = c.Int(nullable: false, identity: true),
BlogId = c.Int(nullable: false),
})
.PrimaryKey(t => t.Id)
.ForeignKey("dbo.T_Blog", t => t.BlogId, cascadeDelete: true)
.Index(t => t.BlogId);
}
public override void Down()
{
DropForeignKey("dbo.T_Blog", "FeaturedPostId", "dbo.T_Post");
DropForeignKey("dbo.T_Post", "BlogId", "dbo.T_Blog");
DropIndex("dbo.T_Post", new[] { "BlogId" });
DropIndex("dbo.T_Blog", new[] { "FeaturedPostId" });
DropTable("dbo.T_Post");
DropTable("dbo.T_Blog");
}
}
这篇关于EntityFramework尝试获取不存在的列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!