免责声明
我不会尝试从数据库或到数据库刷新任何内容。
我正在寻找的答案应该在上下文中,在内存中找到。
摘要
我遇到了一个奇怪的 EF 行为(我认为这不是一个实际的错误),似乎“相同”的概念操作根据先决条件以两种不同的方式工作。
幸运的是,该案例很简单且可重现。
该模型包含一对相关表;当我将一个表直接添加到其 Context 的 DbSets 时(关系的哪一侧无关紧要)如果该对中的另一个表“已经加载”,有时会建立两者之间的链接,有时不会,这取决于是否其他表(上下文已经知道的表)是“Read_from_DB”或“Added”。
我尝试更好地描述 2 场景的问题:
数据库模型
DB Model是一个简单的主/细节:
-
T_PARENTS
(带有Collection<T_CHILDREN>
) -
T_CHILDREN
(带有Reference<T_PARENTS>
)
场景 1
- 在 DB 中,我们有:
T_PARENTS
中的 1 行使用键“xyz”- 0 行
T_CHILDREN
- 在 c# 中,我们加载所有数据:
-
ctx.T_PARENTS.ToList();
(已加载 1 行) -
ctx.T_CHILDREN.ToList();
(已加载 0 行) -
var existing_parent = ctx.T_PARENTS.First();
-
- 此时
existing_parent
收藏了T_CHILDREN
有 0 行。 - 在 c# 中,我们添加一个新的
T_CHILDREN
和:-
var new_child = new T_CHILDREN() {parent_key = "xyz"};
-
ctx.T_CHILDREN.Add(new_child);
-
- 这里 Context 发挥了它的魔力 并且在对象
existing_parent
中 我们可以找到Collection<T_CHILDREN>
现在有 1 行(刚刚添加的行)。
场景 2
- 在 DB 中,我们有:
T_PARENTS
中的 0 行- 0 行
T_CHILDREN
- 在 c# 中,我们加载所有数据:
-
ctx.T_PARENTS.ToList();
(已加载 0 行) -
ctx.T_CHILDREN.ToList();
(已加载 0 行)
-
- 在 c# 中,我们添加一个新的
T_PARENTS
和:-
var new_parent = new T_PARENTS() {key = "xyz"};
-
ctx.T_PARENTS.Add(new_parent);
-
- 在 c# 中,我们添加一个新的
T_CHILDREN
和:-
var new_child = new T_CHILDREN() {parent_key = "xyz"};
-
ctx.T_CHILDREN.Add(new_child);
-
- 这里 Context 没有产生任何魔法 而对象
new_parent
仍然有Collection<T_CHILDREN>
有 0 行(我们找不到刚刚添加到上下文中的 new_children)。
问题是:
- 为什么?
- 是否有任何函数可以针对上下文调用以“刷新”附加到上下文的所有实体的集合和引用?(...并且不,
ctx.ChangeTracker.DetectChanges()
没有没用 :-))
再次感谢大家!
毫米
最佳答案
这都是关于具有上下文的实体状态。这里使用的最重要的方法是 DbContext.Entry(object)
EntityEntry
返回会给你 EntityState
.
在第一种情况下,existing_parent
已经是一个跟踪对象,在第二种情况下它很可能是分离的,直到您SaveChanges
,或显式设置State
的 EntityEntry
到 EntityState.Added
。
更多原因:在第二种情况下,您将一个对象添加到集合中,但实际上并未告诉上下文本身对其执行任何操作。通过在 EntityEntry
上设置信息,您明确告诉上下文“跟踪此对象”
关于c# - 如何链接添加到 DbSet 的实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32700723/