我似乎正在与命名和理解的结合。
我继承了一个数据库,并正在建立一个MVC网站,我无法获得"数据库优先"工作流程的播放。最后,我手动构建了我的上下文课程,并且一直在愉快地工作。
我现在处于无法添加与其他几个现有实体(多对多实体)的实体。
我的数据库外观(简化了此问题),例如:
ListItem Option OptionListItems
====== ====== ===============
Id Id ListItem_Id
Name Name Option_Id
我的上下文包含一个属性,该属性使我能够获得所有的ListItem:
public virtual DbSet<ListItem> ListItems { get; set; }
,如果我使用一些linq,我会做类似以下操作的事情,并且返回了项目,并且满足了多一的关系,并且我在ListItem
中获得了Option
的列表:
var item = _context.ListItems
.Where(p => p.Id == id)
.Include(p => p.Options)
.SingleOrDefault();
实际上,我必须在数据库中构造交叉引用表,当我试图运行上述查询时,我做过的,我被告知我没有任何对象称为dbo.OptionListItems
。所以我以为我们都很好。
现在,我需要创建一个新的ListItem
并将其链接到一个或多个现有 Option
,而我却亏本了。
一旦我孤立地创建了新的ListItem
并尝试调用listItem.Options.Add(...)
失败,但是如果我尝试获取对特定Option
的引用并尝试执行option.ListItems.Add(...)
。
错误有点有趣,是我拥有的相反表格名称:
{"Invalid object name 'dbo.ListItemOptions'."}
我怀疑在我的上下文上建立一种类型和属性的EF的谷物,直接访问这样的交叉参考表:
public virtual DbSet<OptionListItem> OptionListItems { get; set; }
,但我对创建新关系的模式感到困惑。
我们有这个(多一到多的)声明工作。伪代码:
public class ListItem
{
public ListItem()
{
this.RelatedOptions = new HashSet<OptionListItems>();
}
[Key]
public int Id {get; set;}
public string Name {get; set;}
public virtual ICollection<OptionListItems> RelatedOptions {get; set;}
}
public class Option
{
public Ortion()
{
this.RelatedItems = new HashSet<OptionListItems>();
}
[Key]
public int Id {get; set;}
public string Name {get; set;}
public virtual ICollection<OptionListItems> RelatedItems {get; set;}
}
public class OptionListItems
{
[Key]
public int Id {get; set;}
[Column("ListItemId", Order = 1)]
[ForeignKey("ParentListItem")]
public int ListItemId {get; set;}
[Column("OptionId", Order = 2)]
[ForeignKey("ParentOption")]
public int OptionId {get; set;}
public virtual ListItem ParentListItem {get; set;}
public virtual Option ParentOption {get; set;}
}
这应声明
荣誉归功于史蒂夫·格林(Steve Greene)指向我的正确方向。我的表是由惯例创建的,当我用.Include(p => p.Options)
查询CC_11时工作,但是如果您尝试进行更新,则惯例似乎会崩溃。我不确定为什么,但是在查询时,映射表的构造似乎是<Entity1>+<Entity2>+s
,但是更新时<Entity2>+<Entity1>+s
...
好消息,通过使用Fluentapi,我在实体之间创建了一个特定的映射,并强迫交叉参考表以及查询和更新作品!
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<ListItem>()
.HasMany<Option>(s => s.Options)
.WithMany(c => c.ListItems)
.Map(cs =>
{
cs.MapLeftKey("ListItem_Id");
cs.MapRightKey("Option_Id");
cs.ToTable("OptionListItems");
});
}