【问题标题】:EntityFramework CodeFirst FK association problemEntity Framework Code First FK关联问题
【发布时间】:2011-03-19 15:31:12
【问题描述】:

我正在尝试让 CodeFirst 正常工作,但我遇到了外键和相关对象的问题。这可能是由于我不匹配“约定”并且还不了解如何正确覆盖我的设置中的约定。如果可以的话,请帮忙。

我现有的数据库中有这两个表:

create table locations
(
ID int identity primary key
, name varchar(50) not null
)

create table meetings
(
ID int identity primary key
, whatever varchar(50) null
, LocationID int not null constraint FK_meetings_LocationID foreign key references locations(ID)
)

模型是这样设置的:

public class Location
{
    public int ID { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Meeting> Meetings { get; set; }
}

public class Meeting
{
    public int ID { get; set; }
    public string Whatever{ get; set; }
    public Location HeldAt { get; set; }
}

最后,我的上下文是这样设置的:

public class v1Context : DbContext
{
    public v1Context(string ConnectionString)
        : base(ConnectionString)
    {}

    public DbSet<Location> Locations { get; set; }
    public DbSet<Meeting> Meetings { get; set; }

    //protected override void OnModelCreating(DbModelBuilder modelBuilder)
    //{
    //    modelBuilder.Entity<Location>().HasKey(k => k.ID);
    //    modelBuilder.Entity<Meeting>().HasKey(k => k.ID);
    //}
}

而且,我收到以下错误“执行命令定义时发生错误。有关详细信息,请参阅内部异常”.. InnerExceptin 为:

InnerException = {"Invalid column name 'HeldAt_ID'."}

我尝试了各种 OnModelCreating 咒语,但均未成功。很明显,问题在于它不知道如何将“LocationID”FK 正确导航到带有 ID 字段的 Location 类。但我一直无法弄清楚。

不知何故,我认为,由于它是“Location”类型,并且 Location 类也独立映射到数据库,并且因为数据库中存在适当的 FK 关系,所以它会“弄清楚”。

任何帮助将不胜感激。

【问题讨论】:

    标签: entity-framework ef-code-first entity-framework-4.1


    【解决方案1】:

    您不使用列的默认名称,因此您必须在 OnModelBuilding 中指定它们:

    使用它来将 LocationID 定义为您的外键列,而不是默认的预期 HeldAt_ID:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Meeting>()
            .HasRequired(m => m.HeldAt)
            .WithMany(l => l.Meetings)
            .Map(m => m.MapKey("LocationID"));
    }
    

    【讨论】:

    • 谢谢 - 这“几乎有效!”我现在可以获取会议列表,而不是错误,但是... HeldAt 属性始终为 NULL。
    • 是的,因为您可能没有使用预加载并且您的 HeldAt 属性不是虚拟的,因此 EF 无法为预加载创建动态代理。
    • 哇。臭死了!但是谢谢-您的回答是正确的。对于其他任何人-这似乎是您渴望在 EF 中加载的方式: var meeting = db.Meetings.Include("HeldAt").AsEnumerable().FirstOrDefault(); - 不应该有更强类型的方式来做到这一点吗? yowza :(
    • EF 4.1 中有强类型版本。也不要在 FirstOrDefault 之前使用 AsEnumerable。直接使用 FirstOrDefault。不同之处在于您的调用从数据库加载所有记录并在内存中选择第一个,而直接使用 First 仅返回来自数据库的单个记录。
    猜你喜欢
    • 2011-08-01
    • 2023-04-11
    • 1970-01-01
    • 2011-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多