如何使用Entity Framework 4 Code First(POCO)声明一对一关系

Pau*_*les 12 c# entity-framework one-to-one poco ef-code-first

如何使用Entity Framework 4 Code First(POCO)声明一对一的关系?

我发现了这个问题(实体框架4中的一对一关系),但是答案引用的文章没有用(有一行代码是1-1关系,但没有提到如何定义它).

Chr*_*ini 22

三种方法:

A)声明两个具有导航属性的类.使用其主键上的ForeignKey属性标记其中一个表(从属表).EF从中推断出1:1:

public class AppUser
{
    public int Id { get; set; }

    public string Username { get; set; }

    public OpenIdInfo OpenIdInfo { get; set; }
}

?public class OpenIdInfo
{
    [ForeignKey("AppUser")]
    public int Id { get; set; }

    public string OpenId { get; set; }

    public AppUser AppUser { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

http://weblogs.asp.net/manavi/archive/2011/05/01/associations-in-ef-4-1-code-first-part-5-one-to-one-foreign-key-associations. ASPX

我没有用virtual,你也不应该.*

B)声明一个继承层次结构,其中明确声明了两个表名,从而产生Table-Per-Type和共享主键.

using System.ComponentModel.DataAnnotations;

[Table("AppUser")]
public class AppUser
{
    public int Id { get; set; }

    public string Username { get; set; }

    public OpenIdInfo OpenIdInfo { get; set; }
}

[Table("AdminUser")]      
public class AdminUser : AppUser
{
    public bool SuperAdmin { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

您将获得2个表:一个用于AppUser,一个用于AdminUser.AdminUser与AppUser是1:1并且是Dependent - 意味着您可以删除AdminUser,但如果在AdminUser仍然指向它时删除AppUser,您将收到Constraint Violation Error.

C)在EF中有两种一对一的方法:

Entity-Splitting,您有一个Class,但它存储在主表中,以及一个或多个一对一相关表.

表 - 拆分,其中对象树变平为单个表.例如,具有Address属性的类将具有Address对象的列,如Address_City,将其展平为单个表.

*如果要延迟加载,可以在任何EF属性或集合上包含虚拟.如果将具有延迟加载属性的对象传递给MVC JSON转换器或其他任何遍历对象层次结构的对象,则可能导致无限循环或加载整个DB.Lazy-Loading总是同步完成,阻塞线程,没有任何通知.总而言之,您可以使用它冻结代码,应用程序或服务器的方法列表很长.避免在EF类上使用虚拟.是的,互联网上有很多代码样本使用它.不,你仍然不应该使用它.


The*_*Sky 11

你只是在寻找这样的东西吗?

public class User
{
    public int Id { get; set; }
    public string Username { get; set; }
    public Profile Profile { get; set; }
    public int ProfileId { get; set; }
}

public class Profile
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string PostalCode { get; set; }
    // etc...
}

public class UserMapping : EntityConfiguration<User>
{
    public UserMapping()
    {
        this.HasKey(u => u.Id);
        this.Property(u => u.Username).HasMaxLength(32);

        // User has ONE profile.
        this.HasRequired(u => u.Profile);
    }
}

public class ProfileMapping : EntityConfiguration<Profile>
{
    public ProfileMapping()
    {
        this.HasKey(p => p.Id);
        this.Property(p => p.FirstName).HasMaxLength(32);
        this.Property(p => p.LastName).HasMaxLength(32);
        this.Property(p => p.PostalCode).HasMaxLength(6);
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:是的我没有VS在我面前,但你需要在当前添加以下行UserMapping而不是HasRequired添加ProfileId属性(而不是Profile_Id你添加的):

this.HasRequired(u => u.Profile).HasConstraint((u, p) => u.ProfileId == p.Id);
Run Code Online (Sandbox Code Playgroud)

我目前认为没有办法解决这个问题,但我确信它会改变,因为我们只是在CTP4中.如果我能说:我会很高兴:

this.HasRequired(u => u.Profile).WithSingle().Map(
    new StoreForeignKeyName("ProfileId"));
Run Code Online (Sandbox Code Playgroud)

这样我就不必包含ProfileId属性了.也许目前有一种方法可以解决这个问题,但我仍然要到凌晨才能想到:).

.Include("Profile")如果要包含"导航属性",还要记得打电话.