Debug 对 Linq to Sql 有什么影响吗?
关于 Table<TEntity>.Attach(),据说它的作用就是可以在不同的DataContext当中附加数据,让被附加的数据(实体)即使在外部(DataContext上下文之外)修改也可以让别的DataContext中的对应数据得以更新。
假设我已经有一个Category的实体类与对应的数据库表。
相关类代码如下:
1
public class DataAccess
2
{
3
private static DLContext dtx;
4![](/Images/OutliningIndicators/InBlock.gif)
5
static DataAccess()
6
{
7
dtx = new DLContext();
8
dtx.Log = Console.Out;
9
}
10![](/Images/OutliningIndicators/InBlock.gif)
11
public static DLContext Instance
12
{
13
get
14
{
15
return dtx;
16
}
17
}
18
19
public static void Attach(Category cy)
20
{
21
dtx.GetTable<Category>().Attach(cy, true);
22
}
23![](/Images/OutliningIndicators/InBlock.gif)
24
}
![](/Images/OutliningIndicators/None.gif)
2
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
3
![](/Images/OutliningIndicators/InBlock.gif)
4
![](/Images/OutliningIndicators/InBlock.gif)
5
![](/Images/OutliningIndicators/InBlock.gif)
6
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
7
![](/Images/OutliningIndicators/InBlock.gif)
8
![](/Images/OutliningIndicators/InBlock.gif)
9
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
10
![](/Images/OutliningIndicators/InBlock.gif)
11
![](/Images/OutliningIndicators/InBlock.gif)
12
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
13
![](/Images/OutliningIndicators/InBlock.gif)
14
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
15
![](/Images/OutliningIndicators/InBlock.gif)
16
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
17
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
18
![](/Images/OutliningIndicators/InBlock.gif)
19
![](/Images/OutliningIndicators/InBlock.gif)
20
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
21
![](/Images/OutliningIndicators/InBlock.gif)
22
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
23
![](/Images/OutliningIndicators/InBlock.gif)
24
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
1
static void Main(string[] args)
2
{
3
TestAttach();
4
Console.Read();
5
}
6![](/Images/OutliningIndicators/None.gif)
7
public static void TestAttach()
8
{
9
using (DLContext ctx = new DLContext())
10
{
11
var category = (from c in ctx.GetTable<Category>() select c).FirstOrDefault();
12
string name = category.Name;
13
DataAccess.Attach(category);
14![](/Images/OutliningIndicators/InBlock.gif)
15
Console.WriteLine("Category ID={0},Name={1}", category.KeyID, category.Name);
16![](/Images/OutliningIndicators/InBlock.gif)
17
category.Name = "After modifying" + DateTime.Now.ToString();
18![](/Images/OutliningIndicators/InBlock.gif)
19
var category2 = (from c in DataAccess.Instance.GetTable<Category>() where c.KeyID == category.KeyID select c).SingleOrDefault();
20
Console.WriteLine("After changing the value of property.");
21
Console.WriteLine("Category ID={0},Name={1}", category.KeyID, category.Name);
22
Console.WriteLine("Category2 ID={0},Name={1}", category2.KeyID, category2.Name);
23
Console.WriteLine("Reference equeals ={0}", Object.ReferenceEquals(category, category2));
24
}
25
}
![](/Images/OutliningIndicators/None.gif)
2
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
3
![](/Images/OutliningIndicators/InBlock.gif)
4
![](/Images/OutliningIndicators/InBlock.gif)
5
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
6
![](/Images/OutliningIndicators/None.gif)
7
![](/Images/OutliningIndicators/None.gif)
8
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
9
![](/Images/OutliningIndicators/InBlock.gif)
10
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
11
![](/Images/OutliningIndicators/InBlock.gif)
12
![](/Images/OutliningIndicators/InBlock.gif)
13
![](/Images/OutliningIndicators/InBlock.gif)
14
![](/Images/OutliningIndicators/InBlock.gif)
15
![](/Images/OutliningIndicators/InBlock.gif)
16
![](/Images/OutliningIndicators/InBlock.gif)
17
![](/Images/OutliningIndicators/InBlock.gif)
18
![](/Images/OutliningIndicators/InBlock.gif)
19
![](/Images/OutliningIndicators/InBlock.gif)
20
![](/Images/OutliningIndicators/InBlock.gif)
21
![](/Images/OutliningIndicators/InBlock.gif)
22
![](/Images/OutliningIndicators/InBlock.gif)
23
![](/Images/OutliningIndicators/InBlock.gif)
24
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
25
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
为什么当我不设断点的时候,会出现Exception:
"An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext. This is not supported."
当我在13行 DataAccess.Attach(category);处设了一个断点,而且用鼠标放在category上查看了一下属性值,继续运行,它就不会出错,一切正常了!!!!
是什么原因啊?????
---------------------------------------------------------------------
经大侠指引,终天知道原来因为Category 表中有一个外键,对于实体类Category, 有一个字段:
private EntityRef<Parent>
必须在调用 Attach()方法之前,先令
_Parent=default(EntityRef<Parent>
综上所述,为了方便使用,我在Category类中加了一个Detach()方法:
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
必须在调用 Table<TEntity>.Attach()方法之前,先调用category.Detach()方法。