首页 > 代码库 > 关于Entity Framework关系配置,提示列名XXXX_Id无效的问题

关于Entity Framework关系配置,提示列名XXXX_Id无效的问题

问题描述 :

数据库中有两张表,如下:

技术分享

Member(会员)表有外键RoleId,对应的是Role(角色)表的主键Id,业务逻辑是Member表的RoleId必须与Role表的Id对应(但在设计数据表时没有设置外键,使用EF(Entity Framework,下同)来配置)

首页Member的代码如下:

技术分享
    public partial class Member
    {
        public int Id { get; set; }

        public string Name { get; set; }

        public string Password { get; set; }

        public bool Delete{ get; set; }

        public int RoleId { get; set; }

        public virtual Role Role { get; set; }
    }
View Code

Role表的代码如下:

技术分享
    public partial class Role
    {
        public int Id { get; set; }

        public string Name { get; set; }

        public virtual IList<Member> Members { get; set; }
    }
View Code

Member、Role的关系代码如下:

技术分享
public class MemberMap : EntityTypeConfiguration<Member>
    {
        public MemberMap()
        {
            this.ToTable("Member");
            this.HasKey(m => m.Id);
            this.HasRequired(m => m.Role).WithMany().HasForeignKey(m => m.RoleId);
        }
    }
View Code
技术分享
    public class RoleMap: EntityTypeConfiguration<Role>
    {
        public RoleMap()
        {
            this.ToTable("Role");
            this.HasKey(r => r.Id);
        }
    }
View Code

EF操作类如下:

技术分享
public partial class EFContext<T> : DbContext where T : class
    {
        public EFContext(): base("name=MyConnectionString")
        {
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            Database.SetInitializer<EFContext<T>> (null);
            modelBuilder.Configurations.Add(new MemberMap());
            modelBuilder.Configurations.Add(new RoleMap());
            base.OnModelCreating(modelBuilder);
        }

        public DbSet<T> Table { get; set; }

        public IQueryable<T> GetList(Expression<Func<T,bool>> where)
        {
            return this.Table.Where(where);
        }
    }
View Code

程序运行时提示异常,

技术分享

 

 

展开详情信息如下:

技术分享

使用SQL Profiler发现生成的代码如下:

技术分享

 

这里多查询了Role_Id,实际RoleId已经是外键了。

解决方法是WithMany()配置映射,即修改MemberMap为如下:

public class MemberMap : EntityTypeConfiguration<Member>
    {
        public MemberMap()
        {
            this.ToTable("Member");
            this.HasKey(m => m.Id);
            this.HasRequired(m => m.Role).WithMany(r => r.Members).HasForeignKey(m => m.RoleId);
        }
    }

此时再运行控制台程序,没有异常,SQL Profiler如下:

技术分享

 

可能有人会问,如果确实在MemberMap中使用WithMany()而不是WithMany(r=>r.Members)呢?

此时修改方式如下:

注释或删除Role实体代码中的Members属性

技术分享
public partial class Role
    {
        public int Id { get; set; }

        public string Name { get; set; }

        //public virtual IList<Member> Members { get; set; }
    }
View Code

修改MemberMap为上面所述的:

技术分享
public class MemberMap : EntityTypeConfiguration<Member>
    {
        public MemberMap()
        {
            this.ToTable("Member");
            this.HasKey(m => m.Id);
            this.HasRequired(m => m.Role).WithMany().HasForeignKey(m => m.RoleId);
        }
    }
View Code

最后重新运行程序,没有异常

技术分享

 

关于Entity Framework关系配置,提示列名XXXX_Id无效的问题