实体框架6,无效的列名称 - 不正确的映射

时间:2014-06-24 15:21:45

标签: entity-framework

我通过添加ForeignKey(“Route”)数据注释解决了这个问题:

[ForeignKey("Route")]
public Guid rnh_rtefk { get; set; }

这是我第一次尝试使用EF。

我使用EF 6.0.0.0

在我的MVC应用程序中使用Code First从数据库创建了一个模型

在我的数据库中,我有一个Routes表和一个RunSheetHeader表。一个路由可以有许多RunSheetHeader,RunSheetHeader可以有一个Route。 Routes主键是Routes.rte_pk,它映射到外键:RunSheetHeader.rnh_rtefk。

生成的代码是:

public partial class Route
{
    public Route()
    {
        RunSheetHeaders = new HashSet<RunSheetHeader>();
    }

    [Key]
    public Guid rte_pk { get; set; }

    [Required]
    [StringLength(50)]
    public string rte_name { get; set; }

    public virtual ICollection<RunSheetHeader> RunSheetHeaders { get; set; }
}

[Table("RunSheetHeader")]
public partial class RunSheetHeader
{
    public RunSheetHeader()
    {
        RunSheetDetails = new HashSet<RunSheetDetail>();
    }

    [Key]
    public Guid rnh_pk { get; set; }

    [Column(TypeName = "date")]
    public DateTime rnh_date { get; set; }

    public Guid rnh_rtefk { get; set; }

    public virtual Route Route { get; set; }

    public virtual ICollection<RunSheetDetail> RunSheetDetails { get; set; }
}

这来自Context类:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Route>()
        .HasMany(e => e.RunSheetHeaders)
        .WithRequired(e => e.Route)
        .HasForeignKey(e => e.rnh_rtefk)
        .WillCascadeOnDelete(false);

    modelBuilder.Entity<RunSheetHeader>()
        .HasMany(e => e.RunSheetDetails)
        .WithRequired(e => e.RunSheetHeader)
        .HasForeignKey(e => e.rnd_rnhfk)
        .WillCascadeOnDelete(false);
}

我得到的错误是:

“无效的列名称'Route_rte_pk'。”

并且SQL在SQL事件探查器中显示为:

SELECT 
    1 AS [C1], 
    [Extent1].[rnh_pk] AS [rnh_pk], 
    [Extent1].[rnh_date] AS [rnh_date], 
    [Extent1].[rnh_rtefk] AS [rnh_rtefk], 
    [Extent1].[Route_rte_pk] AS [Route_rte_pk]
    FROM [dbo].[RunSheetHeader] AS [Extent1]

从阅读其他关于类似问题的答案来看,映射正确的外键似乎是一个问题,但它看起来像我已经正确完成了。谁能发现我所缺少的东西?

感谢您的帮助

2 个答案:

答案 0 :(得分:1)

我找到了两种可能的解决方案:

    1。
    [ForeignKey("Route")]
    public Guid rnh_rtefk { get; set; }

    或2.

    [ForeignKey("rnh_rtefk")]
    public virtual Route Route { get; set; }
    

    两者都摆脱了错误,但我被告知第二种选择是更好的选择。

答案 1 :(得分:0)

下面的代码运行得很好,你确定你的OnModelCreating被很好地调用了吗?

namespace testef {
    public partial class Route {
        public Route() {
            RunSheetHeaders = new HashSet<RunSheetHeader>();
        }

        [Key]
        public Guid rte_pk { get; set; }

        [Required]
        [StringLength(50)]
        public string rte_name { get; set; }

        public virtual ICollection<RunSheetHeader> RunSheetHeaders { get; set; }
    }

    [Table("RunSheetHeader")]
    public partial class RunSheetHeader {
        public RunSheetHeader() {
            //RunSheetDetails = new HashSet<RunSheetDetail>();
        }

        [Key]
        public Guid rnh_pk { get; set; }

        [Column(TypeName = "date")]
        public DateTime rnh_date { get; set; }

        public Guid rnh_rtefk { get; set; }

        public virtual Route Route { get; set; }

        //public virtual ICollection<RunSheetDetail> RunSheetDetails { get; set; }
    }
    // ---------------

    public class TestEFContext : DbContext {
        public TestEFContext(String cs)
            : base(cs) {
            Database.SetInitializer<TestEFContext>(new DropCreateDatabaseAlways<TestEFContext>());             
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder) {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<Route>()
                .HasMany(e => e.RunSheetHeaders)
                .WithRequired(e => e.Route)
                .HasForeignKey(e => e.rnh_rtefk)
                .WillCascadeOnDelete(false);

            //modelBuilder.Entity<RunSheetHeader>()
            //    .HasMany(e => e.RunSheetDetails)
            //    .WithRequired(e => e.RunSheetHeader)
            //    .HasForeignKey(e => e.rnd_rnhfk)
            //    .WillCascadeOnDelete(false);
        }

        public DbSet<Route> Routes { get; set; }

    }

    class Program {
        String cs = @"Data Source=ALIASTVALK;Initial Catalog=TestEF;Integrated Security=True; MultipleActiveResultSets=True";
            using (TestEFContext ctx = new TestEFContext(cs)) {
                Route r = new Route {
                    rte_pk = Guid.NewGuid(),
                    rte_name = "test"
                };

                r.RunSheetHeaders.Add(new RunSheetHeader {
                    rnh_pk = Guid.NewGuid(),
                    rnh_date = DateTime.Now
                });
                ctx.Routes.Add(r);
                ctx.SaveChanges();
                Console.WriteLine(ctx.Routes.Count());    
            }

            using (TestEFContext ctx = new TestEFContext(cs)) {
                foreach (Route r in ctx.Routes) {
                    Console.WriteLine(r.rte_name);
                    foreach (RunSheetHeader rsh in r.RunSheetHeaders) {
                        Console.WriteLine("    {0}", rsh.rnh_date);
                    }
                }
            }
        }
    }
}