C# 4.0 设置可选:必需的关系实体框架-fluent API
我有一个用户配置文件关系,用户可以(可选)关联一个配置文件。 在数据库中,PROFILES表与USERS表之间有一个FK(FK可为空) 我想用EF fluent API设置它。我设法做到了,一切正常,但问题是我不能将概要文件中的FK作为类中的属性 因此,在DB中,我有:C# 4.0 设置可选:必需的关系实体框架-fluent API,c#-4.0,entity-framework-4.1,code-first,C# 4.0,Entity Framework 4.1,Code First,我有一个用户配置文件关系,用户可以(可选)关联一个配置文件。 在数据库中,PROFILES表与USERS表之间有一个FK(FK可为空) 我想用EF fluent API设置它。我设法做到了,一切正常,但问题是我不能将概要文件中的FK作为类中的属性 因此,在DB中,我有: [USERS] ID uniqueidentifier PK not null [PROFILES] ID uniqueidentifier PK not null USERID uniqueidentifer FK null
[USERS]
ID uniqueidentifier PK not null
[PROFILES]
ID uniqueidentifier PK not null
USERID uniqueidentifer FK null
在代码中,我有:
public class User { public virtual Profile { get; set; } }
public class Profile { public virtual User { get; set; } }
请注意,DB中的列名不符合EF命名约定
我可以按如下方式配置EF:
HasOptional(u => u.Profile).WithRequired(p => p.User).Map(m => m.MapKey("USERID")).WillCascadeOnDelete();
或者反过来说:
HasRequired(p => p.User).WithOptional(u => u.Profile).Map(m => m.MapKey("USERID")).WillCascadeOnDelete();
在这种情况下,我真的需要使用MapKey映射FK(因为EF使用的命名约定),这似乎是一个不允许我在模型中添加FK的问题
因此,我不能:
public class Profile { public virtual User { get; set; } public Guid? UsreId { get; set; } }
有人知道我怎样才能做到这一点吗
编辑
问题的根源是,如果我不使用.Map(m=>m.MapKey(“USERID”))方法,约定会破坏关系(它期望FK是User_Id),这基本上就像在没有任何参数的情况下使用它一样。如果我使用.Map(m=>m.MapKey(“USERID”))方法,那么它表示我已经将USERID作为模型中的属性(来自内联帮助:配置关系以使用对象模型中未公开的外键属性)和表可以通过指定配置操作进行自定义。如果指定了空配置操作,则将按照约定生成列名
糟糕透了
编辑2设法修复了它(基本上是采用另一种方法)。
将表更改为:
[USERS]
ID uniqueidentifier PK not null
[PROFILES]
-- ID uniqueidentifier PK not null (removed the PK)
USERID uniqueidentifer PK not null, FK not null -- (the PK is also the FK)
在运行SQL探查器并查看在那里运行的查询之后,我来到这里。
根据用户ID查询每个用户的optionl配置文件。WARE条款类似于:
SELECT *
FROM PROFILES
WHERE ID = @userId -- ID was the PK
所以我发现PROFILES表中的PK在这种情况下也必须是FK,并且映射可以保持简单:
HasOptional(u => u.Profile).WithRequired(p => p.User);
还是在另一端
HasRequired(p => p.User).WithOptional(u => u.Profile);
这一条很有帮助:
干杯 您需要将重点放在正确映射实体本身上,然后关系就可以正常工作了。关于关键点的约定如下:
class Program
{
static void Main(string[] args)
{
// replace your connection string here
using (var userContext = new UserContext("UserProfile"))
{
var u = new User { UserId = Guid.NewGuid(), Name = "John", Profile = new Profile() { ProfileId = Guid.NewGuid(), SomeValue = "x" } };
userContext.Users.Add(u);
userContext.SaveChanges();
var users = userContext.Users.ToList();
foreach (var user in users)
{
Console.WriteLine(user.Name);
if (user.Profile != null)
{
Console.WriteLine(user.Profile.ProfileId);
}
}
var profiles = userContext.Profiles.Where(p => p.User.Name == "John").ToList();
}
}
}
public class UserContext : DbContext
{
public UserContext(string connectionString)
: base(connectionString)
{
}
public DbSet<User> Users { get; set; }
public DbSet<Profile> Profiles { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<User>().Property(u => u.UserId).HasColumnName("ID");
modelBuilder.Entity<Profile>().Property(p => p.ProfileId).HasColumnName("ID");
modelBuilder.Entity<User>().HasOptional(u => u.Profile).WithRequired(p => p.User);
}
}
public class User
{
public Guid UserId { get; set; }
public string Name { get; set; }
public Profile Profile { get; set; }
}
public class Profile
{
public Guid ProfileId { get; set; }
public User User { get; set; }
public string SomeValue { get; set; }
}
类程序
{
静态void Main(字符串[]参数)
{
//在此处替换连接字符串
使用(var userContext=newusercontext(“UserProfile”))
{
var u=新用户{UserId=Guid.NewGuid(),Name=“John”,Profile=newprofile(){ProfileId=Guid.NewGuid(),SomeValue=“x”};
userContext.Users.Add(u);
userContext.SaveChanges();
var users=userContext.users.ToList();
foreach(用户中的var用户)
{
Console.WriteLine(用户名);
if(user.Profile!=null)
{
Console.WriteLine(user.Profile.ProfileId);
}
}
var profiles=userContext.profiles.Where(p=>p.User.Name==“John”).ToList();
}
}
}
公共类UserContext:DbContext
{
公共用户上下文(字符串连接字符串)
:基本(连接字符串)
{
}
公共数据库集用户{get;set;}
公共数据库集配置文件{get;set;}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
基于模型创建(modelBuilder);
modelBuilder.Entity().Property(u=>u.UserId).HasColumnName(“ID”);
modelBuilder.Entity().Property(p=>p.ProfileId).HasColumnName(“ID”);
modelBuilder.Entity();
}
}
公共类用户
{
公共Guid用户标识{get;set;}
公共字符串名称{get;set;}
公共配置文件{get;set;}
}
公共班级简介
{
公共Guid配置文件ID{get;set;}
公共用户{get;set;}
公共字符串SomeValue{get;set;}
}
你说的是对的。问题是我想在Profile类中有一个UserId属性(映射到数据库中的FK列)和User属性。