【发布时间】:2016-10-06 16:50:23
【问题描述】:
我正在尝试在我的项目中创建和关联实体。用户可以有许多角色、声明和登录。另一方面,一个声明或登录只能有一个用户,而一个角色也可以有多个用户。我有用 fluent 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");
});
}
如您所见,我的数据库表不遵循实体框架的约定,而不是使用“User_Id”作为外键,外键简单地命名为“用户”。但是,我不断收到此“无效的列名:User_Id”异常消息。
我尝试通过调用方法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;
}
}
【问题讨论】:
-
您的实体模型是否有一个用户属性作为键?至于错误消息,这是运行时错误,还是您正在使用迁移?如果迁移,请在更新时使用 -verbose 开关以查看有关错误的更多详细信息...例如 update-database -verbose。最后,在没有看到模型类的情况下,我质疑 ManyToMany 映射...您是说一个用户有很多用户...而一个角色有很多角色?您的用户实体上有 ICollection
用户吗? -
@MatthewHilgenfeld:是的,这是一个错字,感谢您的指出,刚刚修复它。当我调试我的网站并尝试注册用户时,这是运行时错误。 User 作为 Claim 和 Login 实体的虚拟属性存在,而对于 Role 实体,它是虚拟属性 IList
. -
我通常使用属性作为键,并使用例如映射HasRequired().WithMany().HasForeignKey(),但我没有看到您定义的映射有任何问题。是否有另一个未显示的实体具有约定试图为其定义键的用户属性?
-
我明白了。我可以使用属性作为键,但是除非我想要不同的约定,否则我将不得不以某种方式定义列名。不,我没有另一个定义了“用户”属性的实体。我想如果我至少可以确定这个无效列名错误对应于哪个表,我可以更接近解决方案。现在它可以与任何表格一起使用,这更令人困惑。
-
@MatthewHilgenfeld:既然你提到了它,我意识到我的所有属性都是受保护的(不是公共的),并且我有所有实体的构造函数。这会是个问题吗?我编辑了原始帖子以包含除 User 之外的三个实体类的实体定义。
标签: c# sql-server entity-framework orm foreign-keys