在EF6中,我们有两种方法来声明两个表之间的关系:
注释属性
Fluent API
今天(偶然)我删除了两个表之间的一个关系,一切都运行良好。我很惊讶,因为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:很多,所以它是否意味着Fluent API大部分时间用于1:1?
答案 0 :(得分:2)
实体框架有一些您不需要明确定义的约定。
来自https://msdn.microsoft.com/en-us/library/jj679962(v=vs.113).aspx#Anchor_2
除了导航属性,我们建议您包含 表示依赖对象的类型上的外键属性。 与主要主键具有相同数据类型的任何属性 属性,名称遵循以下格式之一 表示关系的外键:&#39;&lt; navigation property name&gt;&lt;主要主键属性名称&gt;&#39;,&#39;&lt; principal class name&gt;&lt;主键属性名称&gt;&#39;或&#39;&lt;主要主键属性 名称&gt;&#39 ;.如果找到多个匹配,则在。中给出优先级 上面列出的订单。外键检测不区分大小写。什么时候 检测到外键属性,Code First推断出多重性 基于外键的可空性的关系。如果 该属性可以为空,然后将该关系注册为 可选的;否则,关系会按要求注册。