Помогите сопоставить модель предметной области с свободно используемым API EF4.1? - PullRequest
1 голос
/ 20 июня 2011

Я новичок в EF и свободном API. Мой администратор БД решил, что он хочет отобразить «первичное» гражданство человека с флагом Is_Primary в таблице гражданства. Итак, наша БД выглядит примерно так:

**Person Table**
Person_Id    int           identity  (PK)
First_Name   nvarchar(30)
...

**Citizenship_Table**
Citizenship_Person_Id  int identity  (PK)
Person_Id              int
Country_Code           char(2)
Is_Primary             byte
...

**Country_Table**
Country_Code     char(2)  (PK)
Country_Name     varchar(30)
...

Мне действительно не нужен флаг Is_Primary в моей модели домена. Вместо этого я хочу, чтобы мой домен выглядел примерно так:

public class Person
{
   public int Id {get; set;}
   ...
   public virtual ICollection<Country> Citizenships {get; set;}
   public Country PrimaryCitizenship {get; set;}
}

public class Country
{
   public int Code {get; set;}
   public string Name {get; set;}
}

Есть ли способ сопоставить этот сценарий?

1 Ответ

0 голосов
/ 21 июня 2011

Невозможно сопоставить ваше предложение модели домена с заданной структурой таблицы. По моему мнению, это также неправильно - с точки зрения домена - вводить флаг Is_Primary в таблицу гражданства (которая в основном является таблицей соединений между Person и Country).

Домен говорит, что у человека может быть одно первичное гражданство (или, возможно, нет), но никогда много . Это неправильно выражено в структуре таблицы: столбец Is_Primary может быть задан для более чем одной страны для данного человека. Также сложно изменить основное гражданство для человека, потому что вам придется искать все записи в таблице гражданства, принадлежащей этому человеку, если есть другая страна, помеченная как основная, а затем сбросьте этот флаг, прежде чем установить флаг для новой страны .

Это правильно выражено в вашей модели, что означает, что Person должен иметь внешний ключ к таблице Country (обязательный или необязательный). Для изменения основного гражданства потребуется только установить для этого ФК другое значение. Дублирующие первичные флаги невозможны в этой модели.

Если вы измените структуру таблицы следующим образом ...

**Person Table**
Person_Id                int           identity  (PK)
First_Name               nvarchar(30)
PrimaryCountry_Code      char(2)                 (FK to Country table)
...

**Citizenship_Table**
Person_Id                int                     (PK)
Country_Code             char(2)                 (PK)

**Country_Table**
Country_Code             char(2)                 (PK)
Country_Name             varchar(30)
...

... возможно сопоставление вашей модели:

modelBuilder.Entity<Person>()
    .Property(p => p.Id)
    .HasColumnName("Person_Id");

modelBuilder.Entity<Person>()
    .Property(p => p.Name)
    .HasColumnName("First_Name")
    .HasMaxLength(30);

modelBuilder.Entity<Person>()
    .HasMany(p => p.Citizenships)
    .WithMany()
    .Map(a => {
        a.MapLeftKey("Person_Id");
        a.MapRightKey("Country_Code");
        a.ToTable("Citizenship");
    });

modelBuilder.Entity<Person>()
    .HasOptional(p => p.PrimaryCitizenship) // or .HasRequired(...)
    .WithMany()
    .Map(a => a.MapKey("PrimaryCountry_Code"))
    .WillCascadeOnDelete(false);

modelBuilder.Entity<Country>()
    .HasKey(c => c.Code)
    .Property(c => c.Code)
    .HasColumnName("Country_Code")
    .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None)
    .HasMaxLength(2)
    .IsFixedLength()
    .IsUnicode(false);

modelBuilder.Entity<Country>()
    .Property(c => c.Name)
    .HasColumnName("Country_Name")
    .HasMaxLength(30)
    .IsUnicode(false);

Не решение вашей проблемы, а пища для обсуждения с вашим администратором базы данных.

...