我正在尝试创建并关联项目中的实体。用户可以拥有许多角色,声明和登录。另一方面,声明或登录只能有一个用户,而角色也可以有许多用户。我使用流畅的API定义了关系:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
modelBuilder.Entity<User>().HasMany(u => u.Claims).WithRequired(cl => cl.User).Map(m => m.MapKey("User"));
modelBuilder.Entity<Claim>().HasRequired(cl => cl.User).WithMany(u => u.Claims).Map(m => m.MapKey("User"));
modelBuilder.Entity<User>().HasMany(u => u.Logins).WithRequired(lg => lg.User).Map(m => m.MapKey("User"));
modelBuilder.Entity<Login>().HasRequired(lg => lg.User).WithMany(u => u.Logins).Map(m => m.MapKey("User"));
modelBuilder.Entity<User>().HasMany(u => u.Roles).WithMany(ro => ro.Users).Map(userRoles =>
{
userRoles.ToTable("Users_Roles");
userRoles.MapLeftKey("User");
userRoles.MapRightKey("Role");
});
modelBuilder.Entity<Role>().HasMany(ro => ro.Users).WithMany(u => u.Roles).Map(userRoles =>
{
userRoles.ToTable("Users_Roles");
userRoles.MapLeftKey("User");
userRoles.MapRightKey("Role");
});
}
如您所见,我的数据库表不遵循实体框架的约定,而不是使用&#39; User_Id&#39;作为外键,外键简称为“用户”。但是,我一直得到这个&#39;无效的列名:User_Id&#39;异常消息。
我尝试通过调用方法Map()和MapKey()来使用上面的代码定义外键列名,但没有占优势。为什么会这样?我写的映射代码错了吗?有人可以帮忙吗?
PS:异常错误消息非常无用,我不知道这个列名称错误与哪个表相关联。有谁知道如何使异常消息显示表名是什么,而不仅仅是列名?谢谢。
此外,我还添加了用于声明,登录和角色实体的代码(删除了不相关的方法)。
public class Claim
{
public string Id { get; protected set; }
public string Type { get; protected set; }
public string Value { get; protected set; }
public virtual User User { get; protected set; }
public Claim() { }
public Claim(string id, User user, string type, string value)
{
Id = id;
User = user;
Type = type;
Value = value;
}
}
public class Login
{
public string Id { get; protected set; }
public string Provider { get; protected set; }
public string Key { get; protected set; }
public DateTime? DateLoggedin { get; protected set; }
public virtual User User { get; protected set; }
public Login() { }
public Login(string id, string provider, string key, DateTime? dateLoggedIn = null)
{
Id = id;
Provider = provider;
Key = key;
DateLoggedin = dateLoggedIn;
}
}
public class Role
{
public string Id { get; protected set; }
public string Title { get; protected set; }
public string Description { get; protected set; }
public bool IsAdmin { get; protected set; }
public bool IsBanned { get; protected set; }
public IList<User> Users { get; protected set; }
public Role() { }
public Role(string id, string title, string description, bool isAdmin, bool isBanned)
{
Id = id;
Title = title;
Description = description;
IsAdmin = isAdmin;
IsBanned = isBanned;
}
}
答案 0 :(得分:0)
User_Id列是由EF约定创建的,因为您使用与导航程序相同的名称将键映射到属性。
您可以删除.Map()部分并让EF处理该键,或者在Claim和Login类中定义一个键属性,并将其映射到流畅的api中。我个人会做后者。
E.g:
public class Claim
{
public string Id { get; protected set; }
public string Type { get; protected set; }
public string Value { get; protected set; }
public virtual User User { get; protected set; }
public int UserId{get;set;}
public Claim() { }
}
在你的ModelCreating中
modelBuilder.Entity<User>().HasMany(a=>a.Claims).WithRequired(a=>a.User).HasForeignKey(a=>a.UserId);
如果您创建'EntityNameId'(UserId,ClaimId等)的关键字段,那么EF约会将自动将其映射为您的外键,而不使用流畅的映射。但是,如果您的名字是其他名称(UsernameId或其他),则必须显式提供映射。 Some reading on that.