Entity Framework Code-First — определение отношений с MembershipUser

Я пытаюсь понять, как лучше всего определить классы POCO, чтобы иметь возможность использовать функцию Code-first в Entity Framework.
Я хочу определить некоторые отношения внешнего ключа в своих классах, между пользователем, а также между самими классами. . Например, рассмотрим следующие 3 класса:

Public class Job
{
    public int JobID {get; set;}
    public string JobTitle {get; set;}
    public virtual ICollection<Resume> Resumes {get; set;} // Is this correct at all? How to access all resumes for a certain job? (many-to-many relationship between Job and Employee)
}

Public class Resume
{
    public int EmployeeID {get; set;} // or should it be: public virtual Employee EmployeePerson?
    public int JobID {get; set;} // or should it be: public virtual Job UserJob?
    public DateTime EmploymentDate {get; set;}
}  

public class Employee
{
    public int EmployeeID {get; set;}
    public int UserID{ger; set;} // or should it be: public virtual MembershipUser User?
    public ICollection<Resume> Resumes {get; set;} // Is this correct at all? 
}

Пользователь является пользователем членства, который находится в System.Web.Security, который проходит аутентификацию с помощью FormsAuthentication или ActiveDirectoryAuthentication. Вопросы упоминаются в коде (в виде комментариев). Но для уточнения:

  • Должен ли я определять объекты в отношениях и использовать .Include каждый раз, когда они мне нужны, или лучше хранить идентификаторы объектов и пытаться получить данные из этого идентификатора каждый раз, когда мне это нужно? Должен ли я использовать другой подход при работе с классом MembershipUser вместо моих определенных классов?
  • Как еще можно использовать virtual, кроме включения ленивой загрузки? Где я должен избегать этого и где я должен его использовать?

Спасибо.

ОБНОВЛЕНИЕ: я только что протестировал определение Employee с помощью определения ublic virtual MembershipUser User. В результате в моей таблице было добавлено 4 столбца:

  • Пользователь_Электронная почта,
  • User_Comment,
  • Пользователь_Одобрен,
  • User_LastLoginDate,
  • User_LastActivityDate

Ничего уникального для пользователя (User_Email определяется как обнуляемый). Итак, если вы хотите, чтобы в ваших классах был пользователь, напишите оболочку для MembershipUser или просто сохраните UserID.
Спасибо, Ладислав и Сергей.




Ответы (2)


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

Таким образом, ваша модель будет выглядеть так:

public class Resume
{
    public int ID {get; set;}
    // or should it be: public virtual Employee EmployeePerson? 
    // --> yep, easier for you, innit?
    public Employee Employee {get; set;} 

    // or should it be: public virtual Job UserJob? --> yep :)
    public virtual Job Job {get; set;}

    public DateTime EmploymentDate {get; set;}
}  

public class Employee
{
    public int EmployeeID {get; set;}

    // or should it be: public virtual MembershipUser User? 
    // --> yes, as an approach, but read on for clarification.
    public virtual MembershipUser User {get; set;}

    // Is this correct at all? ---> needs to be declared as virtual
    public virtual ICollection<Resume> Resumes {get; set;}
}

Ваш класс Job в порядке, насколько я могу судить.

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

  • Одно замечание о свойстве навигации MembershipUser: боюсь, вам придется написать оболочку для класса MembershipUser, потому что, насколько я помню, у него нет конструктора по умолчанию, и поэтому EF, вероятно, не сможет его создать. для вас на ленивой загрузке.

  • О последствиях пометки свойства как virtual вы можете взглянуть на этот вопрос: Какие эффекты может иметь ключевое слово virtual в Entity Framework 4.1 POCO Code First?

person Sergi Papaseit    schedule 12.04.2011
comment
Спасибо, Серджи, не заметил, что MembershipUser не имеет конструктора по умолчанию. - person Kamyar; 12.04.2011
comment
@Kaymar - Пожалуйста. Кстати, я сказал это навскидку, так что не верьте мне на слово. Проверьте! :) - person Sergi Papaseit; 12.04.2011
comment
@Kaymar - Только что проверил: у него есть конструктор по умолчанию, но это protected, так что для всех целей и намерений его нет;) - person Sergi Papaseit; 12.04.2011

В случае кода сначала я бы, вероятно, использовал это:

public class Job
{
    public virtual int JobId {get; set;}
    public virtual string JobTitle {get; set;}
    public virtual ICollection<Resume> Resumes {get; set;} 
}

public class Resume
{
    [Key, Column(Order = 0)]
    public virtual int EmployeeId {get; set;}
    [Key, Column(Order = 1)] 
    public virtual int JobId {get; set;} 

    public virtual DateTime EmploymentDate {get; set;}
    public virtual Employee Employee {get; set;}
    public virtual Job Job {get; set;}
}  

public class Employee
{
    public virtual int EmployeeId {get; set;}
    public virtual int UserId {ger; set;} 
    public virtual User User {get;set;}
    public virtual ICollection<Resume> Resumes {get; set;} 
}

Внешние ключи в сущности — это плохо, но они значительно упрощают работу в EF. Если вы не используете свойство внешнего ключа, EF определит другой тип отношений. Виртуальное ключевое слово в свойстве навигации предназначено для отложенной загрузки, а виртуальное ключевое слово в других сопоставленных свойствах — для отслеживания изменений.

person Ladislav Mrnka    schedule 12.04.2011
comment
Спасибо Ладислав. Как EF ведет себя с public virtual User User в таблице сотрудников? EF определяет его как сложный тип? - person Kamyar; 13.04.2011
comment
Это сложный тип или сущность? - person Ladislav Mrnka; 13.04.2011
comment
Это MembershipUser, который определен в .NET в пространстве имен System.Web.Security. - person Kamyar; 13.04.2011
comment
@Ladislav: я попробовал, и в моей таблице 4 строки. Я обновлю вопрос... - person Kamyar; 13.04.2011
comment
И вы хотите сохранить все свойства пользователя членства в таблице сотрудников или вы хотите иметь отношение к таблице членства? - person Ladislav Mrnka; 13.04.2011
comment
@Ладислав: Я просто хочу отношений. Вы предлагаете лучший способ, чем тот, который я упомянул в разделе обновления моего вопроса? - person Kamyar; 13.04.2011
comment
Если вы хотите, чтобы пользователь отношения не мог быть сопоставлен как сложный тип, а как свойство навигации к другому объекту. Это потребует сопоставления пользователя членства как объекта. - person Ladislav Mrnka; 13.04.2011
comment
@Ладислав: Спасибо! Я узнал много нового, читая ваши посты. - person Kamyar; 13.04.2011