Кодекс сущности Entity One-to-One Relationship - PullRequest
9 голосов
/ 07 октября 2011

У меня есть следующие две модели

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 Ответ

8 голосов
/ 07 октября 2011

Я думаю, что ваша реализация неверна. AFAIK, Вы не можете определить отношения один-к-одному, используя этот подход в EF.
Взгляните на сгенерированную базу данных, в вашей таблице Periods определен столбец Account_Id. Вот что вы должны определить:

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)");
    }
}

Для получения дополнительной информации об отношениях «один к одному», прочитайте серию блогов г-на Манави по адресу этот адрес .
Обновление
Исходя из вашего комментария, если вы хотите получить ссылку на Account из Period, вы можете добавить атрибут ForeignKey в первичный ключ своей учетной записи.

Хороший образец находится по адресу по этому адресу (часть с заголовком "Сопоставить один с нулем или одно отношение")

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...