In EF6 we have two ways to declare relationship between two tables:
Annotations Attributes
Fluent API
Today (by accident) I removed one relationship between two tables and everything kept working well. I was very surprised because there was no way EF would know how those two tables are connected.
Tables look like that:
[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);
}
}
Here is the test I made: It's an integration test, that connects to the real database, gets items with notes and tests the 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);
}
It passes! It loads all notes! How come?!
I kept investigating and it turned out that in case of 1:many relationship I totally don't have to have any relationship in the code. The only time I need it is with 1:1 relationship. Am I'm missing something? Most of relationships are 1:many, so does it mean Fluent API is used for 1:1 most of the time?