Entity Framework Code-First-определение отношений с MembershipUser
Я пытаюсь понять лучший способ определить мои классы POCO, чтобы иметь возможность использовать функцию Entity Framework code-first.
Я хочу определить некоторые отношения внешнего ключа в моих классах, между пользователем, а также между самими классами. Например, рассмотрим следующие 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
помимо включения ленивой загрузки? Где я должен избегать его и где я должен использовать это?
спасибо.
обновление: я только что протестировал, чтобы определить сотрудника с ublic virtual MembershipUser User
определение. В результате было добавлено 4 столбца в моей таблице:
- User_Email,
- User_Comment,
- User_IsApproved,
- User_LastLoginDate,
- User_LastActivityDate
ничего уникального для пользователя (User_Email определяется как nullable). Так что если вы хотите иметь пользователя в своих классах, напишите обертку для 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, вероятно, не сможет создать его для вас при ленивой загрузке.о влиянии маркировки a собственность как
virtual
, вы можете взглянуть на этот вопрос:какой эффект(ы) может иметь виртуальное ключевое слово в коде Entity Framework 4.1 POCO в первую очередь?
в случае кода сначала я бы, вероятно, использовал это:
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 определит другой тип взаимоотношений. Виртуальное ключевое слово в свойстве навигации предназначено для ленивой загрузки, а виртуальное ключевое слово в других сопоставленных свойствах-для отслеживания изменений.