Нужно ли использовать свойство ClassId для представления отношения в Code First (Entity Framework)? - PullRequest
1 голос
/ 26 декабря 2011

Я использую структуру сущностей (сначала код).

Я хотел бы знать, действительно ли мне нужно использовать свойство с Id для отношений с другой сущностью, как показано в коде ниже.

public class User
{
    public int Id { get; set; }
    public string Login { get; set; }
    public string Password { get; set; }
    public int ProfileId { get; set; }
    public Profile Profile{ get; set; }
}

public class Profile
{
    public int Id { get; set; }
    public string Description{ get; set; }
}

Для этого способа, когда я вставляю пользователя, устанавливая свойство profileid, работает отлично.

Но когда я не использую свойство profileid в классе Profile,

public class User
{
    public int Id { get; set; }
    public string Login { get; set; }
    public string Password { get; set; }
    public Profile Profile{ get; set; }
}

public class Profile
{
    public int Id { get; set; }
    public string Description{ get; set; }
}

при выполнении метод вставки добавляет еще одну запись профиля.Почему?

Мое сопоставление:

public class EntityMapping<Entity> : EntityTypeConfiguration<Entity> where Entity : EntityBase
{
    public EntityMapping()
    {
        HasKey(e => e.Id);
        Property(e => e.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    }
}

public class UserMapping : EntityMapping<User>
{
    public UserMapping() : base()
    {
         ToTable("USER");
         Property(p => p.Id).HasColumnName("USER_CD_USER");
         Property(p => p.Login).HasColumnName("USER_TX_LOGIN").HasMaxLength(10).IsRequired();
         Property(p => p.Password).HasColumnName("USUA_TX_PASSWORD").HasMaxLength(8).IsRequired();
         HasRequired(e => e.Profile).WithMany(p => p.Users).Map(p => p.MapKey("PROF_CD_PROFILE"));
     }
}

public class ProfilelMapping : EntityMapping<Profile>
{
    public ProfileMapping()
        : base()
    {
        ToTable("PROFILE");
        Property(p => p.Id).HasColumnName("PROF_CD_PROFILE");
        Property(p => p.Description).HasColumnName("PROFILE_DS_PROFILE").HasMaxLength(20).IsRequired();
        HasMany(e => e.Users).WithRequired(p => p.Profile);
    }
}

Ответы [ 2 ]

1 голос
/ 26 декабря 2011

Вы задаете два вопроса.

Нужно ли использовать свойство FK?

Нет, не так, но поведение EF меняется, используете вы его или нет. Подробнее об этом - в отдельном ответе и в связанной статье блога.

Почему EF снова вставляет профиль?

Создание отношений с существующими субъектами требует особой осторожности. EF не проверяет, существует ли ваша сущность в базе данных - вы должны сообщить об этом EF. Вот один из многих способов, как этого добиться (без загрузки профиля из базы данных):

var user = GetNewUserSomewhere();
context.Users.Add(user);

// Dummy profile representing existing one.
var profile = new Profile() { Id = 1 };
// Informing context about existing profile.
context.Profiles.Attach(profile);

// Creating relation between new user and existing profile
user.Profile = profile;

context.SaveChanges();
0 голосов
/ 26 декабря 2011

Краткий ответ: Да.Так работает EF.Необходимо хранить внешний ключ в выделенном свойстве.Вы когда-нибудь генерировали структуру классов из базы данных?Это всегда добавляет это ключевое свойство.В некоторых случаях вам не нужно загружать свойство Profile, но позже вы можете захотеть получить его.Для этого используется выделенное свойство ProfileId, оно будет считывать значение ключа и загружать объект.

...