基于更新后的问题
不,你不能使用ORM提供的强类型功能来实现这一点,无论如何都不行。
- Two-Way Navigation Property
- At least a ForeignKey/Principal property(
SchoolId
on Child
)
- Having a shadow foreign key to the parent
performing a raw query (which beats the idea of having ORM for strong typing) and being DB agnostic at the same time
// Bad!! Database specific dialect, no strong typing
ctx.Database.ExecuteSqlCommandAsync("UPDATE Childs SET schoolId = {0}", schoolId);
当您选择使用ORM时,您必须接受所选ORM框架的某些技术限制。
如果您想遵循领域驱动设计(DDD)并从实体中删除所有特定于数据库的字段,则很难将您的领域模型用作实体。
DDD和ORM之间的协同效应不太好,有更好的方法,但需要采用不同的架构方法(即:CQRS+ES(具有事件溯源的命令查询职责分离))。
这与DDD的配合更好,因为事件源自事件溯源只是简单且不可变的消息类,可以作为序列化JSON存储在数据库中并重新播放以重构域实体的状态。但这是一个不同的话题,人们可以写整整一本关于这个主题的书。
旧答案:
上述情况仅在单个数据库操作中可能发生,如果您的
Child
对象具有导航属性/“返回引用”到父级。
class School
{
public ICollection<Child> Childrens {get; set;}
...
}
并且
class Child
{
public int Id {get; set;}
public int SchoolId { get; set; }
public School { get; set; }
...
}
然后你可以这样做:
ctx.Childs.Add(new Child { Id = 7352, SchoolId = 5, ... })
当然,你首先必须知道学校ID并且确认其有效性,否则如果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's tracked
// schoolId = 5 for example
child.SchoolId = schoolId;
ctx.SaveChanges();
SchoolId
是其中之一,使用单个操作添加新的子元素是另一个有意义的操作。 - Tseng