实体框架代码优先 - 定义与MembershipUser的关系

时间:2011-04-12 09:55:08

标签: entity-framework .net-4.0 lazy-loading foreign-key-relationship entity-framework-4.1

我正在尝试理解定义POCO类的最佳方法,以便能够使用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,还是更好地存储对象的ID并尝试每次需要时从该ID获取数据?在处理MembershipUser类而不是我定义的类时,我应该使用不同的方法吗?
  • 除了启用延迟加载之外,virtual还有什么其他用途?我应该在哪里避免它,我应该在哪里使用它?

谢谢。

更新:我刚刚测试过定义具有ublic virtual MembershipUser User定义的员工。结果是我的表中添加了4个列:

  • User_Email,
  • User_Comment,
  • User_IsApproved,
  • User_LastLoginDate,
  • User_LastActivityDate

用户没有任何独特之处(User_Email被定义为可为空)。因此,如果您希望在您的类中拥有用户,请为MembershipUser编写一个包装器,或者只存储UserID 谢谢Ladislav和Sergi。

2 个答案:

答案 0 :(得分:5)

我建议将外键声明为导航属性,这样您就可以直接访问相关属性而无需自己从数据库中显式检索它(它将被延迟加载)。

所以你的模型看起来像是:

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的命名方式进行一点控制。

答案 1 :(得分:3)

如果代码优先,我可能会使用它:

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将定义different type of relationship。导航属性上的虚拟关键字用于延迟加载,其他映射属性上的虚拟关键字用于更改跟踪。