Helper /中间类在数据库(实体框架)中没有列
本文关键字:框架 实体 中间 数据库 Helper | 更新日期: 2023-09-27 18:12:05
首先,我是实体框架的新手,并且正在从我自己编写的数据库框架迁移现有项目,因此我在我选择的解决方案中具有相当大的灵活性。
从我目前的研究来看,一切似乎都是正确的。但是,在构建数据库时,我编写的helper类的表中没有列(除了主键外)。下面是这些类的最简化版本,它们的关系在fluent API中定义。
public class Concept
{
public long ID { get; set; }
[Index(IsUnique = true), MaxLength(255)]
public string Name { get; set; }
}
public class Tag
{
public long ID { get; set; }
public virtual Content Subject { get; set; }
public virtual Concept Concept { get; set; }
}
public class Helper
{
public long ID { get; set; }
public virtual Content Subject { get; set; }
public virtual List<Tag> Instances { get; set; }
// Helper functionality
}
public class Content
{
public long ID { get; set; }
public virtual Helper Helper { get; set; }
public Content() { Helper = new Helper() { Subject = this }; }
}
<<p> 上下文/strong> protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Tag>()
.HasRequired(t => t.Concept);
modelBuilder.Entity<Tag>()
.HasRequired(t => t.Subject);
modelBuilder.Entity<Helper>()
.HasRequired(t => t.Subject)
.WithRequiredDependent(c => c.Helper);
modelBuilder.Entity<Helper>()
.HasMany(t => t.Instances);
modelBuilder.Entity<Content>()
.HasRequired(c => c.Helper)
.WithRequiredPrincipal();
base.OnModelCreating(modelBuilder);
}
Program.cs
static void Main(string[] args)
{
Content content = null;
using (var context = new Context())
{
content = context.Content.Find(1);
if (content == null)
{
content = new Content();
context.Content.Add(content);
context.Helper.Add(content.Helper);
context.SaveChanges();
}
}
}
值得一提的是,当保存数据时,Helper被分配了一个ID,但在第二次加载父类(Content)时,Helper不会像我期望的"virtual"关键字那样惰性加载。我怀疑这是由同样的问题引起的,导致表中没有数据。
我尝试了EF提供的数据注释和流畅的API方法,但似乎有一些基本的东西是我误解的。我希望保留这个helper类,因为它有助于更好地组织代码。
因为我花了相当多的时间研究这些关系/api,并搜索谷歌/SO没有找到任何东西来解决这个问题,特别是任何帮助将非常感激!
<标题>更新:解决方案感谢评论中的一个问题,我意识到我希望在实体类型本身的表中看到多对多关系的键(即在Helpers表中)。然而,在多对多关系中,键总是放在一个单独的表中(类型名称的连接),该表以前没有创建过。
将'.WithMany();'添加到OnModelCreating函数的Helper部分,如下所示
modelBuilder.Entity<Helper>()
.HasMany(t => t.Instances)
.WithMany();
正确地定义了多对多关系,并且按照预期生成了HelperTags表。这是因为多对多关系是单向的(helper总是引用Tags,而Tags从不引用helper)。这也是为什么'WithMany'没有任何参数(因为Tag类中不存在Helper属性)。修复这个简单的疏忽就解决了问题!
标题>您可能比在on ModelCreate中需要更努力地工作。您可能应该使用标识符重新设计您的类,像这样:
public class Tag
{
public long Id { get; set; }
public long SubjectId { get; set; }
public long ConceptId { get; set; }
public virtual Content Subject { get; set; }
public virtual Concept Concept { get; set; }
}
您需要保持ID名称与对象名称完全相同+ ID和EF将神奇地将所有内容链接起来。如果你不希望它们是必需的,那么让id为空(c# 6 == long? SubjectId
)。
另外,我已经更改了ID -> ID;我不知道这是否重要。我记得有一次我必须这样做才能使事情正常工作(那是几年前的事了),从那以后我一直这样做。
考虑阅读:
- 实体框架代码第一公约
关系公约》
除了导航属性,我们建议您包括表示依赖对象的类型上的外键属性。
与主键具有相同数据类型的任何属性属性,并使用遵循以下格式之一的名称表示关系的外键:
<navigation property name><principal primary key property name>
<principal class name><primary key property name>
<principal primary key property name>
如果找到多个匹配项,则按顺序给出优先级上面列出的。
外键检测不区分大小写。
来自MSDN的示例代码:
在下面的示例中,使用导航属性和外键来定义Department和Course类之间的关系。
public class Department
{
// Primary key
public int DepartmentID { get; set; }
public string Name { get; set; }
// Navigation property
public virtual ICollection<Course> Courses { get; set; }
}
public class Course
{
// Primary key
public int CourseID { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
// Foreign key
public int DepartmentID { get; set; }
// Navigation properties
public virtual Department Department { get; set; }
}