实体框架代码第一对一关系

时间:2011-10-07 15:36:38

标签: entity-framework code-first

我有以下两个模型

public class Account
{
     public int Id { get; set; }
     public string Name { get; set; }
     public int CurrentPeriodId { get; set; }

     [ForeignKey("CurrentPeriodId")]
     public virtual Period CurrentPeriod { get; set; }

     public virtual ICollection<Period> Periods { get; set; }
}

public class Period
{
     public int Id { get; set; }
     public int AccountId { get; set; }
     public DateTime StartDate { get; set; }
     public DateTime EndDate { get; set; }

     public virtual Account Account { get; set; }
}

我正在尝试运行以下查询:

from p in context.Periods
where p.AccountId == accountId &&
      p.Id == p.Account.CurrentPeriodId
select p.StartDate

我得到一个sql异常,说“无效的列名Account_AccountId”。

我知道我可以从帐户方面处理此问题并执行类似

的操作
from a in context.Accounts
where a.Id == id
select a.CurrentPeriod.StartDate

但我想知道如何设置关系以使其他查询起作用。我错过了什么?

1 个答案:

答案 0 :(得分:8)

我认为你的实施是错误的。 AFAIK,你不能在EF中使用这种方法定义一对一的关系 查看生成的数据库,您的Account_Id表中定义了Periods列。以下是您必须定义的内容:

public class Account
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int CurrentPeriodId { get; set; }
    public virtual Period CurrentPeriod { get; set; }
    public virtual ICollection<Period> Periods { get; set; }
}

public class Period
{
    public int Id { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
}

然后,上下文和初始化程序:

public class TestContext : DbContext
{
    public DbSet<Account> Accounts { get; set; }
    public DbSet<Period> Periods { get; set; }

static TestContext()
{ 
    Database.SetInitializer(new DbInitializer());
}

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Account>().HasRequired(a => a.CurrentPeriod).WithMany().HasForeignKey(a => a.CurrentPeriodId);
    }
}

class DbInitializer : DropCreateDatabaseAlways<TestContext>
{
    protected override void Seed(TestContext context)
    {
        context.Database.ExecuteSqlCommand("ALTER TABLE Accounts ADD CONSTRAINT uc_Period UNIQUE(CurrentPeriodId)");
    }
}

有关一对一关系的更多信息,请阅读Manavi先生在this address的博客系列。
更新
根据您的评论,如果您希望引用Account中的Period,则可以在帐户的主键上添加ForeignKey属性。

一个好的样本位于this address(标题为“将一个地图划分为零或一个关系”的部分)