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

发布于 2024-10-31 21:39:27 字数 1628 浏览 0 评论 0原文

我试图了解定义 POCO 类的最佳方法,以便能够使用实体框架代码优先功能。
我想在我的类中、用户之间以及类本身之间定义一些外键关系。例如,考虑以下 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 还有什么用途?我应该在哪里避免它,在哪里应该使用它?

谢谢。

更新:我刚刚测试了使用公共虚拟MembershipUser User定义来定义Employee。结果是我的表中添加了 4 列:

  • User_Email、
  • User_Comment、
  • User_IsApproved、
  • User_LastLoginDate、
  • User_LastActivityDate

没有任何用户特有的列(User_Email 被定义为可为空)。因此,如果您想在类中包含用户,请为 MembershipUser 编写一个包装器或仅存储 UserID。
谢谢拉迪斯拉夫和塞尔吉。

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 from that ID every time I need to? Should I use a different approach when dealing with MembershipUser 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.
Thank you Ladislav and Sergi.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

余生再见 2024-11-07 21:39:27

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

所以你的模型看起来像:

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

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 the MembershipUser 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?

新雨望断虹 2024-11-07 21:39:27

如果首先使用代码,我可能会使用这个:

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文