我有
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; }
}
我的IdentityUser实现有INT PK。我希望在MyUser中有一个导航属性,而在另一侧则没有。我更喜欢数据注释。是否可以使用IdentityUser PK进行导航? (EF v 6.1.3)
UPD#1。 依赖类型 - MyUserProfile。并且它不必包含MyUser类型的导航属性。
答案 0 :(得分:2)
我问你为什么要这样做,一个更好的解决办法可能就是把它放在一张桌子上,因为它会更快,除非它们都是大型实体而且配置文件是可选的(但是即使这样,你也可以有一个单独的专栏,说明额外的数据是否可用。
由于您似乎要求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; }
}
在DbContext
上,使用以下内容覆盖OnModelCreating
:
modelBuilder.Entity<MyUserProfile>()
.HasRequired(m => m.User)
.WithOptional(m => m.Profile);
**完全披露:我也总是喜欢数据注释而不是Fluent配置语法,但我迄今为止还没有避免它,并且它确实没有任何缺点。对于像这样基本的东西,你不希望它受到属性的微小变化的影响。
这会生成以下架构,以便在我们预期的两个表之间同步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对该选项的回答。
答案 1 :(得分:2)
我想提一下我的测试与@RudiVisser关于创建的数据库的答案的细微差别。
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);
}
与他的回答相反,我没有观察到创建单独的MyUser_Id
外键。 MyUserProfiles.Id
已正确配置为主键和外键。因此,任何想要使用这种配置的人都应该尝试一下,但要仔细观察生成的迁移代码。
我的工具集:Visual Studio 2013,EntityFramework 6.1.3 nuget package。
答案 2 :(得分:0)
我确定你是否想要那个,但你可以&#34;拆分表&#34;。 换句话说,对两个实体使用相同的表。
像这样:
[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; }
}