似乎没有类似的问题可以解决这个问题。我正在使用Entity Framework 5,MVC 4,.NET 4.5作为我的Web应用程序,使用VS 2012设计。
我有两个应该是亲子关系的课程。
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
// Other stuff
public int? JoggerId { get; set; }
public virtual Jogger Jogger{ get; set; }
}
和
public class Jogger
{
[Key]
public int JoggerId { get; set; }
[Required, ForeignKey("UserId")]
public int UserId { get; set; }
public virtual UserProfile UserProfile { get; set; }
}
使用Fluent API:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<UserProfile>()
.HasOptional(x => x.Jogger)
.WithRequired(c => c.UserProfile)
.WillCascadeOnDelete(true);
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
base.OnModelCreating(modelBuilder);
}
用户可以是慢跑者,也可以不是慢跑者,即一个用户为零或一个慢跑者。 EF Powertools edmx视图中的关系看起来很好,但是我无法使用Foreign键来使用UserProfile UserId。
我的Fluent API是错误的还是我的模特?请帮忙 - 我真的被卡住了!
答案 0 :(得分:3)
使用Fluent API进行映射是可以的,但是从模型中删除UserProfile.JoggerId
和Jogger.UserId
属性,它应该可以正常工作。原因是实体框架使用Jogger
的主键作为UserProfile
的外键,因此您不需要(也不能)具有单独的外键属性。这种一对一的关系称为“Shared Primary Key Association”。
修改强>
请注意,Jogger
的主键(作为关系的依赖关系)在数据库中不自动生成,只有UserProfile
的主键是自动生成的(作为关系的主体)。
如何将UserProfile
或Jogger
或两者插入数据库的方式如下:
如果您想在没有UserProfile
的情况下插入Jogger
,只需将其添加到上下文中:
using (var context = new MyContext())
{
var newUserProfile = new UserProfile();
// no key needs to be supplied, the DB will take care
context.UserProfiles.Add(newUserProfile);
context.SaveChanges();
}
如果您想在一个步骤中插入UserProfile
Jogger
:
using (var context = new MyContext())
{
var newUserProfile = new UserProfile { Jogger = new Jogger() };
// no key needs to be supplied, neither for UserProfile
// nor for Jogger, the DB will take care
context.UserProfiles.Add(newUserProfile);
context.SaveChanges();
}
如果您要插入Jogger
(现有Jogger
必须为UserProfile
):
using (var context = new MyContext())
{
var newJogger = new Jogger { JoggerId = someExistingUserProfileId };
// a valid key needs to be supplied, otherwise you would violate a FK
// constraint in the database
context.Joggers.Add(newJogger);
context.SaveChanges();
}
修改2
对于您没有UserId
直接可用但Name
(作为经过身份验证的用户)的用例,您必须首先从数据库加载密钥或UserProfile
:
// we are in an ASP.NET MVC controller action here
using (var context = new MyContext())
{
string userName = User.Identity.Name;
int? userId = context.UserProfiles
.Where(u => u.Name == userName)
.Select(u => (int?)u.UserId)
.SingleOrDefault();
if (userId.HasValue)
{
var newJogger = new Jogger { JoggerId = userId.Value };
context.Joggers.Add(newJogger);
context.SaveChanges();
}
}
或者加载UserProfile
也可以:
using (var context = new MyContext())
{
string userName = User.Identity.Name;
UserProfile userProfile = context.UserProfiles
.Where(u => u.Name == userName)
.SingleOrDefault();
if (userProfile != null)
{
userProfile.Jogger = new Jogger();
// I believe you don't need to set the JoggerId key now,
// I'm not sure though
context.SaveChanges();
// Change tracking recognizes the new Jogger
// no context.Joggers.Add is required
}
}