C# EntityFramework正在尝试获取不存在的列

C# EntityFramework正在尝试获取不存在的列,c#,entity-framework,ef-code-first,entity-framework-6,data-annotations,C#,Entity Framework,Ef Code First,Entity Framework 6,Data Annotations,EntityFramework正在尝试获取不存在的列,而外键属性没有帮助 在我的例子中,我有两个具有单对多关系的表: T_Blog - Id - FeaturedPost T_Post - Id - BlogId 我定义了实体数据模型 public class T_Blog { [Key] public int Id {get;set;} public int? FeaturedPostId {get;set;} [ForeignKey("Featu

EntityFramework正在尝试获取不存在的列,而外键属性没有帮助

在我的例子中,我有两个具有单对多关系的表:

  T_Blog
- Id
- FeaturedPost

  T_Post
- Id
- BlogId
我定义了实体数据模型

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;}
}
public class T\u博客
{
[关键]
公共int Id{get;set;}
public int?FeaturedPostId{get;set;}
[ForeignKey(“FeaturedPostId”)]
公共虚拟T_Post特性Post{get;set;}
公共虚拟ICollection Posts{get;set;}
}
公营邮政
{
[关键]
公共int Id{get;set;}
[必需]
public int BlogId{get;set;}
[ForeignKey(“博客ID”)]
公共博客{get;set;}
}
定义此元数据意味着每次我试图执行db.T_Post.Where(…).ToList()时,EF都试图获取
T_Blog_Id

我明白了,只要我的T_博客有两个对T_帖子的引用,EF就会尝试获取这两个ID

ps:是的,我知道这种类型的数据模型不是最优的,但这种类型的非规范化在我的情况下是需要的(至少到目前为止)


如何正确定义第二个关系,以便EF知道取什么?

在我花了一个小时的研究之后,我找到了答案。如果EF无法定义映射,则不仅应定义
ForeignKey
,还应定义
InverseProperty

public class T_Blog
{
    [Key]
    public int Id {get;set;}
    public int? FeaturedPostId {get;set;}

    [ForeignKey("FeaturedPostId")]
    public virtual T_Post FeaturedPost {get;set;}
    [InverseProperty("Blog")]
    public virtual ICollection<T_Post> Posts {get;set;}
}
public class T\u博客
{
[关键]
公共int Id{get;set;}
public int?FeaturedPostId{get;set;}
[ForeignKey(“FeaturedPostId”)]
公共虚拟T_Post特性Post{get;set;}
[反向财产(“博客”)]
公共虚拟ICollection Posts{get;set;}
}

发现

在我研究了一个小时后,我找到了答案。如果EF无法定义映射,则不仅应定义
ForeignKey
,还应定义
InverseProperty

public class T_Blog
{
    [Key]
    public int Id {get;set;}
    public int? FeaturedPostId {get;set;}

    [ForeignKey("FeaturedPostId")]
    public virtual T_Post FeaturedPost {get;set;}
    [InverseProperty("Blog")]
    public virtual ICollection<T_Post> Posts {get;set;}
}
public class T\u博客
{
[关键]
公共int Id{get;set;}
public int?FeaturedPostId{get;set;}
[ForeignKey(“FeaturedPostId”)]
公共虚拟T_Post特性Post{get;set;}
[反向财产(“博客”)]
公共虚拟ICollection Posts{get;set;}
}

找到

您应该使用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> 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; }
}

您应该使用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> 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; }
}

fluentapi非常适合避免这种混淆。我要试一试。到目前为止,属性更方便,只要代码编写更少,并且(更重要的是)在发生更改时重构更少。Fluent API非常适合避免这种混淆。我要试一试。到目前为止,属性更方便,只要代码编写更少,并且(更重要的是)在发生更改时重构更少。