Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架:一对零关系_C#_Asp.net Mvc_Entity Framework - Fatal编程技术网

C# 实体框架:一对零关系

C# 实体框架:一对零关系,c#,asp.net-mvc,entity-framework,C#,Asp.net Mvc,Entity Framework,我有 public class MyUser : IdentityUser<int,MyLogin,MyUserRole,MyUserClaim> { public virtual MyUserProfile Profile { get; set; } } public class MyUserProfile { public int Id { get; set; } public string FirstName { get; set; }

我有

public class MyUser : IdentityUser<int,MyLogin,MyUserRole,MyUserClaim>
{
     public virtual MyUserProfile Profile { get; set; }
}

public class MyUserProfile
{
     public int Id { get; set; }
     public string FirstName { get; set; }
     public string LastName { get; set; }
}
公共类MyUser:IdentityUser
{
公共虚拟MyUserProfile配置文件{get;set;}
}
公共类MyUserProfile
{
公共int Id{get;set;}
公共字符串名{get;set;}
公共字符串LastName{get;set;}
}
我的IdentityUser实现具有INT PK。我想在MyUser中有一个导航属性,而在另一端没有。我更喜欢数据注释。是否可以使用IdentityUser PK进行导航?(EF v 6.1.3)

UPD#1。
依赖类型-MyUserProfile。而且它不必包含MyUser类型的导航属性。

如果您需要,我可以确定,但您可以“拆分表”。 换句话说,对这两个实体使用相同的表

像这样:

[Table("MyUser ")]
public class MyUser : IdentityUser<int,MyLogin,MyUserRole,MyUserClaim>
{
     public virtual MyUserProfile Profile { get; set; }
}

[Table("MyUser ")]
public class MyUserProfile
{
     [Key]
     public int Id { get; set; }

     public string FirstName { get; set; }
     public string LastName { get; set; }
}
[表(“MyUser”)]
公共类MyUser:IdentityUser
{
公共虚拟MyUserProfile配置文件{get;set;}
}
[表(“MyUser”)]
公共类MyUserProfile
{
[关键]
公共int Id{get;set;}
公共字符串名{get;set;}
公共字符串LastName{get;set;}
}

我想问你为什么要这样做,更好的解决方案可能是将其保存在一个表中,因为这样会更快,除非它们都是大型实体,并且概要文件是可选的(但即使这样,你也可以有一个单独的列,说明额外的数据可用或不可用)

由于您似乎要求1:0..1关系,您可以按如下方式实现它。我知道您需要数据注释,但我真的建议在这里明确*,这样对模型的任何更改都不会导致潜在的意外连锁反应

public class MyUser : IdentityUser<int,MyLogin,MyUserRole,MyUserClaim>
{
     public virtual MyUserProfile Profile { get; set; }
}

public class MyUserProfile
{
     public int Id { get; set; }
     public string FirstName { get; set; }
     public string LastName { get; set; }

     public MyUser User { get; set; }
}
**充分披露:我也总是喜欢数据注释,而不是流畅的配置语法,但迄今为止我一直没有回避它,而且它确实没有缺点。对于像这样基本的东西,您不希望它受到属性的轻微更改的影响

这将生成以下模式,以便在两个表之间同步ID时保持精简,正如我们预期的那样:

        CreateTable(
            "dbo.MyUsers",
            c => new
                {
                    Id = c.Int(nullable: false, identity: true),
                    Test = c.String(),
                })
            .PrimaryKey(t => t.Id);

        CreateTable(
            "dbo.MyUserProfiles",
            c => new
                {
                    Id = c.Int(nullable: false),
                    Test = c.String(),
                })
            .PrimaryKey(t => t.Id)
            .ForeignKey("dbo.MyUsers", t => t.Id)
            .Index(t => t.Id);

正如@grek40所提到的,通过翻转关系的流畅配置(有关更多信息,请参见注释),可以在另一端不使用导航属性的情况下完成此操作,请参见该选项的grek40答案。

关于创建的数据库,我想提及我的测试与@rudiviser的答案略有不同

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

    public virtual MyUserProfile Profile { get; set; }
}

public class MyUserProfile
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}


class MyContext : DbContext
{
    public DbSet<MyUser> Users { get; set; }
    public DbSet<MyUserProfile> Profiles { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<MyUser>()
            .HasOptional(x => x.Profile)
            .WithRequired();
    }
}
与他的回答相反,我没有观察到单独的
MyUser\u Id
外键的创建。
MyUserProfiles.Id
已正确配置为主键和外键。因此,任何想要使用这种配置的人都应该尝试一下,但要仔细观察生成的迁移代码


我的工具集:Visual Studio 2013,EntityFramework 6.1.3 nuget软件包。

请澄清您的预期关系。。。哪一方是主体,哪一方是从属。它是必需的:可选的(1:0-1)还是什么?我想不出一个解决方案,依赖的
MyUserProfile
可以在没有
MyUser
类型的导航属性的情况下生存。因此,无论是流畅的还是数据注释,这个答案的重要部分可能是,
公共MyUser用户{get;set;}
无法通过正常方式避免。@grek40确实,这是一个技术练习,看看它是否可能还是一个要求?如果是前者,您可以通过TPT继承来实现,其中
MyUserProfile
是一个单独的表,但是是
MyUser
的超集。你想要一个这样的例子吗?这根本不是我的问题,我只是在这里阅读,看到大多数答案都失败了,因为“而且它不必包含MyUser类型的导航属性”,而你忽略了它,从而成功地提供了某种工作解决方案;)不要误解我的意思-我读了你的问题,我只是想发布一个完整的工作样本,也可以帮助其他人。我不确定没有导航属性是否可能,但请把它留给我。。。试着做点什么!:)@grek40哈我刚意识到你说的话。这不是你的问题!实际上,这不是你的问题。很抱歉还在想别的办法!嗯,你肯定没有错。我刚刚删除了我的数据库,并生成了另一个没有额外密钥的测试迁移。昨晚我可能在Profile->Users中保留了导航属性。编辑:是的,就是这样,如果导航属性没有生成另一个键或使用数据注释显式地声明FK,那么现在就不能返回导航属性+不管怎样:)@RudiVisser我总是很高兴听到奇怪的行为源于小错误,而不是实际的图书馆问题;)。但是你可以拥有一个导航属性。只需将其包含在fluent api描述中,否则将被视为单独的nav。
public class MyUser
{
    public int Id { get; set; }

    public virtual MyUserProfile Profile { get; set; }
}

public class MyUserProfile
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}


class MyContext : DbContext
{
    public DbSet<MyUser> Users { get; set; }
    public DbSet<MyUserProfile> Profiles { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<MyUser>()
            .HasOptional(x => x.Profile)
            .WithRequired();
    }
}
public override void Up()
{
    CreateTable(
        "dbo.MyUserProfiles",
        c => new
            {
                Id = c.Int(nullable: false),
                FirstName = c.String(),
                LastName = c.String(),
            })
        .PrimaryKey(t => t.Id)
        .ForeignKey("dbo.MyUsers", t => t.Id)
        .Index(t => t.Id);

    CreateTable(
        "dbo.MyUsers",
        c => new
            {
                Id = c.Int(nullable: false, identity: true),
            })
        .PrimaryKey(t => t.Id);
}