Entity Framework Code-First - Defining relationships with MembershipUser
I'm trying to understand the best way to define my POCO classes to be able to use Entity Framework code-first feature.
I want to define some foreign key relations in my classes, between the user and also between the classes themselves. For example consider the following 3 classes: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?
}
The user is a Membership user which is in System.Web.Security
which is being authenticated by FormsAuthentication or ActiveDirectoryAuthentication. The questions are mentioned in the code (as comments). But for clarification:
- Should I define the objects in relations and use
.Include
every time I need them or is it better to store the ID of the objects and try to get the data 开发者_如何学Pythonfrom that ID every time I need to? Should I use a different approach when dealing withMembershipUser
class instead of my defined classes? - What's other uses of
virtual
apart from enabling lazy loading? Where should I avoid it and where should I use it?
Thank you.
UPDATE: I have just tested to define Employee with the ublic virtual MembershipUser User
definition. The result was 4 added columns in my table:
- User_Email,
- User_Comment,
- User_IsApproved,
- User_LastLoginDate,
- User_LastActivityDate
Nothing unique to the user (User_Email is defined as nullable). So If you want to have user in you classes, write a wrapper for MembershipUser
or just store UserID.
I would recommend declaring the Foreign Keys as navigation properties, that way you can always access the related property directly without having to retrieve it explicitly from the database yourself (it will be lazy loaded).
So your model would look like:
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;}
}
Your Job
class is OK as far as I can tell.
To be clear, it will work as well using it as you had it initially, but you'll need to explicitly mark the properties with the ForeignKeyAttribute
, which isn't necessary if you're willing to give up a tiny bit of control on how FK's are named in your database.
One remark about the
MembershipUser
navigation property: I'm afraid you'll need to write a wrapper for theMembershipUser
class because as far as I can recall it doesn't have a default contructor and so EF will probably not be able to instantiate it for you on lazy loading.About the effects of marking a property as
virtual
, you might want to take a look at this question: What effect(s) can the virtual keyword have in Entity Framework 4.1 POCO Code First?
In case of code first I would probably use this:
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;}
}
Foreign keys in entity are bad but they make things much easier in EF. If you don't use foreign key property EF will define different type of relationship. Virtual keyword on navigation property is for lazy loading and virtual keyword on other mapped properties is for change tracking.
精彩评论