Entity Framework Code-First - 使用MembershipUser定义关系

6

我正在尝试理解定义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? 
}

用户是Membership用户,位于System.Web.Security中,正在通过FormsAuthentication或ActiveDirectoryAuthentication进行身份验证。问题在代码中已经提到(作为注释)。但是为了澄清:
  • 我应该定义关系中的对象并在每次需要时使用.Include还是更好地存储对象的ID并且每次需要数据时尝试从该ID获取数据?处理MembershipUser类时是否应该使用不同的方法?
  • virtual的其他用途是什么,除了启用延迟加载?在哪里应该避免使用它,在哪里应该使用它?
谢谢。
更新:我刚刚测试了使用public virtual MembershipUser User 定义Employee的结果是我的表中添加了4个列:
  • User_Email
  • User_Comment
  • User_IsApproved
  • User_LastLoginDate
  • User_LastActivityDate
对用户来说没有什么特别之处(User_Email被定义为可为空)。因此,如果您想在类中拥有用户,请编写一个包装器MembershipUser或仅存储UserID。 谢谢Ladislav和Sergi。
2个回答

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类是可以的。

需要明确的是,如果你愿意放弃对数据库中FK命名的一点控制,那么最初的使用方式也可以正常工作,但你需要显式地用ForeignKeyAttribute标记属性。


谢谢Sergi,我没有注意到MembershipUser没有默认构造函数。 - Kamyar
@Kaymar - 不用谢。顺便说一下,我是凭记忆说的,所以不要完全相信我的话。一定要检查一下! :) - Sergi Papaseit
1
@Kaymar - 刚刚检查了一下:它确实有一个默认构造函数,但是它是“受保护的”,因此就所有目的和意图而言,它并不存在 ;) - Sergi Papaseit

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将定义不同类型的关系。导航属性上的虚拟关键字是用于延迟加载,其他映射属性上的虚拟关键字是用于更改跟踪。

谢谢Ladislav。EF如何处理Employee表中的public virtual User User?EF是否将其定义为复杂类型? - Kamyar
它是复杂类型还是实体? - Ladislav Mrnka
@Ladislav:我只是想建立一个关系。你有没有比我在问题更新部分提到的更好的建议? - Kamyar
如果您希望关系用户不能被映射为复杂类型,而是作为导航属性到其他实体,则需要将成员资格用户映射为实体。 - Ladislav Mrnka
2
@Ladislav:谢谢!通过阅读您的帖子,我学到了许多新东西。 - Kamyar
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接