【发布时间】:2018-06-01 19:24:09
【问题描述】:
我有以下模型类。程序使用EF V6.2.0
public partial class SessionStatus
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public SessionStatus()
{
Sessions = new HashSet<Session>();
}
[Key]
[Column("Id", TypeName ="TinyInt")] // No effect
public byte Id { get; set; } // Becomes SessionStatus_Id for DB operations
[Required]
[StringLength(10)]
public string Status { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Session> Sessions { get; set; }
}
而Session 类是
public partial class Session
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Session()
{
SessionMessages = new HashSet<SessionMessage>();
}
[Key]
public Guid Uid { get; set; }
// ......
public virtual SessionStatus SessionStatus { get; set; }
}
还有下面的代码
using (var ctx = new ProcessContext())
{
ctx.Sessions.Add(new Session { Uid = guid, //...... });
ctx.SaveChanges();
}
得到错误
{"无效的列名'SessionStatus_Id'。"}
数据库表SessionStatus 的列名是Id 而不是SessionStatus_Id(表列SessionStatus_Id 不存在)。为什么 EF 在列名前加上表名?连[Column("Id", TypeName ="TinyInt")]这个属性都没用?
【问题讨论】:
-
SessionStatus_Id不是SessionStatus表的PK,而是从“Session”指向“SessionStatus”的FK。我没有看到您打算用于这种关系的 FK - 如果它不打算反映在数据库模型中,请忽略直接和反向导航属性。如果是,您应该提供正确的 FK 列并相应地调整映射。
-
其实
SessionStatus_Id是不存在的。 -
@ca9163d9 您是否对
SessionStatus_Id进行了完整的程序集构建搜索。可能相关,但我遇到过 EF 有时会将前缀附加到列名。例如,如果我有一个名为“User”的表,并且该表中有一个名为“User”的列,EF 会将其创建为“User_1”。 -
显然。代码优先约定将 FK 列命名为 {OtherTableName}+"_"+"Id"。除非您准确地命名了一个属性,否则它不会出现在您的代码中,但如果您让 EF 为您创建数据库,它将出现在表中。 FK 名称来自 EF 代码优先命名约定,如果您现有的数据库架构与代码优先约定不匹配,则必须调整映射。
-
@slee423 这是不正确的。列名“User”可以在名为“User”的表中,通常的标识符是 [dbname].[dbo].[User].[User]。但是,如果存在重复名称,则会发生您所描述的命名行为,因此如果表“用户”具有“用户”列并且类型具有未映射到该列的属性“用户”。然后表用户将有两个列“用户”和“用户_1”。
标签: c# entity-framework ado.net entity-framework-6