在EF6中,我们有两种方法来声明两个表之间的关系:
今天(偶然)我去掉了两张桌子之间的一段关系,一切都很正常。我很惊讶,因为EF不可能知道这两个表是如何连接的。
表如下所示:
[Table("item")]
public class Item
{
public Item()
{
ItemNotes = new HashSet<ItemNote>();
}
[Key]
[Column("itemID", TypeName = "int")]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int itemID { get; set; }
public ICollection<ItemNote> ItemNotes { get; set; }
}
[Table("itemNotes")]
public class ItemNote
{
[Key]
[Column("id", TypeName = "int")]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Column("itemID", TypeName = "int")]
public int ItemId { get; set; }
[Column("note", TypeName = "varchar")]
[MaxLength(255)]
public string Note { get; set; }
}
Fluent API:
public class MyContext : DbContext
{
public MyContext()
: base("name=MyContext")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer<MyContext>(null);
//I removed this relationship:
//modelBuilder.Entity<Item>().HasMany(i => i.ItemNotes).WithRequired().HasForeignKey(i => i.ItemId);
base.OnModelCreating(modelBuilder);
}
}
这里是我所做的测试:--这是一个集成测试,连接到真实的数据库,获取带有备注的项目,并测试EF:
[TestCase]
public void QueryItemWithItemNotesTest()
{
FniContext fniContext = new FniContext();
int itemId = fniContext.Database.SqlQuery<int>("SELECT TOP(1) itemId FROM item WHERE itemId IN (SELECT itemId FROM dbo.itemNotes)").FirstOrDefault();
var item = fniContext.Items.AsNoTracking()
.Include(i => i.ItemNotes)
.Where(i => i.itemID == itemId).FirstOrDefault();
Assert.IsNotNull(item);
Assert.Greater(item.ItemNotes.Count, 0);
}
它过去了!它装载了所有的笔记!,为什么?!
我一直在调查,结果发现在1:许多关系的情况下,我完全不需要在代码中有任何关系。我唯一需要的是1:1的关系。我是不是漏掉了什么?大多数关系都是1:1,所以这是否意味着在大多数情况下使用了1:1的Fluent API?
发布于 2018-03-08 14:41:07
实体框架有一些不需要显式定义的约定。
来自2
除了导航属性之外,我们建议在表示依赖对象的类型上包括外键属性。任何具有与主体主键属性相同的数据类型并具有以下格式之一的名称的属性都表示关系的外键:“”、“”或“”。如果找到多个匹配项,则按上面列出的顺序确定优先级。外键检测不区分大小写。当检测到外键属性时,代码首先根据外键的空性推断关系的多重性。如果属性为空,则将关系注册为可选关系;否则,关系将按要求注册。
https://stackoverflow.com/questions/49182158
复制相似问题