Kernel Entity Framework: update relationship with identifier only without additional call

I am trying to understand how to deal with the “single navigation situation” described in this document:

Say we have 2 models.

class School
{
   public ICollection<Child> Childrens {get; set;}
   ...
}

and

class Child
{
    public int Id {get; set;}
    ...
}

Thus, this is a one-to-one relation, created by a conditional path, without an explicit foreign key c Child.

So the question is, does it have an instance Childand knows School.Idif there is a way to update this relationship without additionally invoking the database to get the instance School.

+6
source share
2 answers

So the question is, does it have an instance Childand knows School.Idif there is a way to update this relationship without additionally invoking the database to get the instance School.

, . fake stub School Id, Attach DbContext ( , EF, ), Attach Child , Child SaveChanges:

Child child = ...;
var schoolId = ...;

var school = new School { Id = schoolId };
context.Attach(school);
context.Attach(child);
school.Childrens.Add(child);
context.SaveChanges();

: , FK, EF Core /

- , . Track Track.

. "SchoolId".

, School, , Child , shadow API ChangeTracker:

context.Attach(child);
context.Entry(child).Property("SchoolId").CurrentValue = schoolId;
context.SaveChanges();
+5

, , , ORM , ORM ,

  • ForeignKey/Principal (SchoolId on Child)
  • ( ORM ) DB

    // Bad!! Database specific dialect, no strong typing 
    ctx.Database.ExecuteSqlCommandAsync("UPDATE Childs SET schoolId = {0}", schoolId);
    

ORM, ORM.

Domain Driven Design (DDD) db , .

DDD ORM , , ( : CQRS + ES ( Event Sourcing).

DDD, EventSourcing - ( ) , JSON . , .

, Child / " " .

class School
{
   public ICollection<Child> Childrens {get; set;}
   ...
}

class Child
{
    public int Id {get; set;}
    // this is required if you want do it in a single operation
    public int SchoolId { get; set; }
    // this one is optional
    public School { get; set; }
    ...
}

- :

ctx.Childs.Add(new Child { Id = 7352, SchoolId = 5,  ... });

, , , , SchoolId , .

childId, , .

// childId = 7352
var child = ctx.Childs.FirstOrDefault(c => c.Id == childId);
// or use ctx.Childs.Find(childId); if there is a chance that 
// some other operation already loaded this child and it tracked

// schoolId = 5 for example
child.SchoolId = schoolId;
ctx.SaveChanges();
+1

All Articles