无法确定导航属性ASP.NET核心2.0实体框架所代表的关系

时间:2017-10-19 21:46:15

标签: c# asp.net asp.net-mvc entity-framework asp.net-core

我目前正在开发一个使用EntityFramework的ASP.NET应用程序,用于给定代码

public partial class EnumMeta : Meta
{
    public EnumMeta()
    {
        this.Messages = new HashSet<MessageMeta>();
    }

    public bool IsFlag { get; set; }

    public virtual ICollection<MessageMeta> Messages { get; set; }
}

public partial class MessageMeta : Meta
{
    public MessageMeta()
    {
        this.Enums = new HashSet<EnumMeta>();
        this.Receiver = new HashSet<Module>();
        this.Sender = new HashSet<Module>();
    }

    public int MsgId { get; set; }

    public virtual ICollection<EnumMeta> Enums { get; set; }
    public virtual ICollection<Module> Receiver { get; set; }
    public virtual ICollection<Module> Sender { get; set; }
}

我收到错误:

  

无法确定导航属性&EnumMeta.Messages&#39;所代表的关系。类型&#39; ICollection&#39;。手动配置关系,或使用&#39; [NotMapped]&#39;忽略此属性。属性或使用&#39; EntityTypeBuilder.Ignore&#39;在&#39; OnModelCreating&#39;。

这段代码是由EntityFramework使用WPF项目自动生成的,然后将模型带到ASP.NET核心2.0项目中,以实现“#code; first&#34;进入数据库。

我已经尝试在[ForeignKey("MessageMeta")]之上设置public virtual ICollection<MessageMeta> Messages { get; set; }而没有任何正面解决方案。

1 个答案:

答案 0 :(得分:6)

正如我之前评论的那样Entity FrameworkEntity Framework Core 2.0之间存在很多差异,我认为您不能只使用Entity Framework生成的模型并使用{运行Code First {1}}。

根据所描述的模型,看起来Entity Framework Core 2.0MessageMeta具有多对多的关系。

就像今天一样,EnumMeta仍然不支持多对多没有中间类。因此,为了在Entity Framework Core 2.0中执行多对多,您需要中间类。

MessageMeta

EF Core 2.0

EnumMeta

using System.Collections.Generic;

namespace DL.SO.MessageEnum.Web.UI.Models
{
    public class MessageMeta
    {
        public int MsgId { get; set; }

        public List<MessageEnum> EnumMetas { get; set; }
    }
}

MessageEnum(或者你可以称之为EnumMessage) - 中间模型

using System.Collections.Generic;

namespace DL.SO.MessageEnum.Web.UI.Models
{
    public class EnumMeta
    {
        public int EnumId { get; set; }
        public bool IsFlag { get; set; }

        public List<MessageEnum> MessageMetas { get; set; }
    }
}

的DbContext

namespace DL.SO.MessageEnum.Web.UI.Models
{
    public class MessageEnum
    {
        public int MessageMetaId { get; set; }
        public MessageMeta MessageMeta { get; set; }

        public int EnumMetaId { get; set; }
        public EnumMeta EnumMeta { get; set; }
    }
}

appsettings.json

using Microsoft.EntityFrameworkCore;

namespace DL.SO.MessageEnum.Web.UI.Models
{
    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options): base(options) { }

        public DbSet<MessageMeta> Messages { get; set; }
        public DbSet<EnumMeta> Enums { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<MessageMeta>()
                .HasKey(x => x.MsgId);

            modelBuilder.Entity<EnumMeta>()
                .HasKey(x => x.EnumId);

            modelBuilder.Entity<MessageEnum>()
                .HasKey(x => new { x.MessageMetaId, x.EnumMetaId });
            modelBuilder.Entity<MessageEnum>()
                .HasOne(x => x.MessageMeta)
                .WithMany(m => m.EnumMetas)
                .HasForeignKey(x => x.MessageMetaId);
            modelBuilder.Entity<MessageEnum>()
                .HasOne(x => x.EnumMeta)
                .WithMany(e => e.MessageMetas)
                .HasForeignKey(x => x.EnumMetaId);
        }
    }
}

启动

{
  "ConnectionStrings": {
    "AppDbConnection": "Data Source=.\\SQLEXPRESS;Initial Catalog=SO.MessageEnum;Integrated Security=True;MultipleActiveResultSets=False;"
  },
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  }
}

using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using DL.SO.MessageEnum.Web.UI.Models; using Microsoft.EntityFrameworkCore; namespace DL.SO.MessageEnum.Web.UI { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { string dbConnectionString = Configuration.GetConnectionString("AppDbConnection"); services.AddDbContext<AppDbContext>(options => options.UseSqlServer(dbConnectionString) ); services.AddMvc(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseBrowserLink(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); } } }

上运行的命令
Package Manager Console

生成的数据库

enter image description here