Entity Framework 4.1 Code First, One-to-One с одной таблицей, соединяющейся с одним полем ключа составного ключа - PullRequest
2 голосов
/ 22 июля 2011

Я только начинаю с EF4.1 Code First, и мне это очень нравится.

Вот история: класс Codif состоит из ключа из класса Domaine, класса Entite и Referenceкласс и четвертое поле, в котором есть текст.Ссылка и Codif имеют отношение один-к-одному.

Дело в том, что при создании базы данных он создает некоторые уродливые поля в моей сущности Reference, создавая дубликаты полей сущности Codif.Хорошая мысль: однако, когда я манипулирую своим объектом Reference, у меня ожидаемое поведение при обращении к свойству Codif, а повторяющиеся поля невидимы.

Вот код:

public class Reference
{
    public int ReferenceId { get; set; }
    public string Libelle { get; set; }
    public virtual Codif Codif { get; set; }

}

public class Domaine
{
    public int DomaineId { get; set; }
    public string Libelle { get; set; }

}

public class Codif
{
    [Key, Column(Order = 0)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int DomaineId { get; set; }
    [InverseProperty("DomaineId")]
    public virtual Domaine Domaine { get; set; }

    [Key, Column(Order = 1)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int EntiteId { get; set; }
    [InverseProperty("EntiteId")]
    public virtual Entite Entite { get; set; }

    [Key, Column(Order = 2)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int ReferenceId { get; set; }
    [InverseProperty("ReferenceId")]
    public virtual Reference Reference { get; set; }

    [Key, Column(Order = 3)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public string Codification { get; set; }
}

public class Entite
{
    public int EntiteId { get; set; }
    public string Nom { get; set; }
    public string Email { get; set; }
}

И вотрезультат в таблицах (изображения):

Codif

Ссылка

  1. В справочном классе, какя могу указать, что ReferenceId является внешним ключом, который будет использоваться против единственного поля Codif?
  2. Как избавиться от этих дублирующих полей в Reference?
  3. Как удалить Reference_ReferenceId в таблице Codifпри сохранении свойства навигации?

Спасибо за вашу поддержку.

Marc

Редактировать: я работаю с базой данных SQL Compact Edition 4

1 Ответ

0 голосов
/ 22 июля 2011

Замените все ваши атрибуты [InverseProperty("xxx")] на [ForeignKey("xxx")].Я думаю, что это то, что вы на самом деле хотите.[InverseProperty] относится к свойству навигации на другой стороне отношения, которое никогда не может быть скалярным свойством.

Редактировать

Вы можете в дополнение к атрибуту FKустановите атрибут [InverseProperty] в свойстве Reference в вашем классе Codif:

public class Codif
{
//...

    [Key, Column(Order = 2)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int ReferenceId { get; set; }
    [ForeignKey("ReferenceId")]
    [InverseProperty("Codif")] // <-- refers to Codif property in Reference class
    public virtual Reference Reference { get; set; }

//...
}

Но это не является необходимым, потому что EF должен определять правильные отношения между Reference и Codifусловно.(Я не уверен, хотя для отношений один-к-одному.)

Редактировать

Проблемы!

Первое: насколько я могувидите, вы должны указать отношение один-к-одному в Fluent API, потому что EF не может иначе определить, кто является основным и что является зависимым:

modelBuilder.Entity<Reference>()
            .HasOptional(c => c.Codif)
            .WithRequired(c => c.Reference);

Второе: EF все равно будет жаловаться из-за составленного ключа или из-за ReferenceId не один ключ.Если бы ReferenceId был единственным ключом в Codif, он бы работал.

Редактировать

Я пытаюсь понять, чего вы хотите достичь.Очевидно, ваш составной ключ в Codif должен гарантировать, что любая комбинация из четырех значений поля может существовать только один раз.Но это противоречит взаимно-однозначному отношению imo, например, это будут действительные записи таблицы:

Table Codif:
DomaineId    EntiteId    ReferenceId    Codification
----------------------------------------------------
1            1           1              "A"
2            1           1              "A"
1            2           1              "A"
1            1           2              "A"
1            1           1              "B"
etc...

Но, как вы можете видеть: у вас может быть несколько строк с одинаковым ReferenceId, что означаетчто вы не можете иметь отношения один к одному с Reference.Здесь у вас есть 4 Codif сущностей, которые ссылаются на одну и ту же Reference сущность с Id = 1.

Теперь, я думаю, тот факт, что вы хотите иметь отношение один к одному, означает, чтоявляется дополнительным ограничением, поэтому ReferenceId в таблице Codif может встречаться только один раз.Другими словами: строки 2, 3 и 5 в приведенном выше примере недопустимы с точки зрения бизнеса (хотя и действительны с точки зрения БД).

В этом случае я бы фактически сделал ReferenceId единственным ключом вCodif и убедитесь из бизнес-логики, что другие комбинации значений в БД уникальны (запросите, если существует, прежде чем вставить новый Codif).На стороне базы данных вы можете создать уникальный индекс для трех других полей, чтобы гарантировать, что комбинации всегда уникальны в базе данных.EF не может проверить это внутренне, хотя уникальные ограничения еще не поддерживаются.

...