关于Linq2Sql有外键表的更新引发的问题。

  近来用到了Linq2Sql的方法,遇到了一个更新问题。在此记录下来与大家分享。

      废话不多说,请看:

      1.数据库表结构如下:

  需求很简单,一个Order表保存订单,一个OrderDetails保存订单明细。同时2个表有主外键的关系。

      数据库里数据如下:

  

    

    好的,是不是很简单。现在如果我们要把Order_Details表的EntryId等于3的那条记录的Qty更新成200,该怎么做呢?

    Linq2Sql实现起来十分简单,代码如下: 

View Code
 1  static void Main(string[] args)
 2         {
 3             var item = default(Order_Detail);
 4             using (var db = new ToyDataContext())
 5             {           
 6                 item = db.GetTable<Order_Detail>().FirstOrDefault(p => p.EntryId == 3);
 7             }
 8 
 9             if (item != null)
10             {
11                 item.Qry=100;
12                 using (var db=new ToyDataContext())
13                 {
14                     db.GetTable<Order_Detail>().Attach(item);
15                     db.Refresh(System.Data.Linq.RefreshMode.KeepCurrentValues, item);
16                     db.SubmitChanges();
17                 }
18             }
19         }

   当当当,但是在执行的时候,却抛出如下异常

  原来是这个实体对应的表有若干个关联表,在生成实体类时会自动产生:EntityRef<Order> Order这样的属性,但是Linq2Sql默认是延迟加载的,所以在Attach的时候,这些EntityRef还没有加载。

 好了,于是我们想到了可以在首次从数据库查询的时候不启用延迟加载,将DeferredLoadingEnabled设置为false。这样,在执行查询时,将不会为实体加载任何需延迟查询的数据。

代码如下:

View Code
 1   static void Main(string[] args)
 2         {
 3             var item = default(Order_Detail);
 4             using (var db = new ToyDataContext())
 5             {
 6                 db.DeferredLoadingEnabled = false;//不会为实体加载任何需延迟查询的数据
 7                 item = db.GetTable<Order_Detail>().FirstOrDefault(p => p.EntryId == 3);
 8             }
 9 
10             if (item != null)
11             {
12                 item.Qry = 200;
13                 using (var db = new ToyDataContext())
14                 {
15                     db.GetTable<Order_Detail>().Attach(item);
16                     db.Refresh(System.Data.Linq.RefreshMode.KeepCurrentValues, item);
17                     db.SubmitChanges();
18                 }
19             }
20         }

另外还可以通过手动Detach方法,手工移除关联

代码如下:

View Code
 1 static void Main(string[] args)
 2         {
 3             var item = default(Order_Detail);
 4             using (var db = new ToyDataContext())
 5             {
 6                 //  db.DeferredLoadingEnabled = false;//不会为实体加载任何需延迟查询的数据
 7                 item = db.GetTable<Order_Detail>().FirstOrDefault(p => p.EntryId == 3);
 8             }
 9 
10             if (item != null)
11             {
12                 item.Qry = 200;
13                 using (var db = new ToyDataContext())
14                 {
15                     Detatch(item);//Detatch
16                     db.GetTable<Order_Detail>().Attach(item);
17                     db.Refresh(System.Data.Linq.RefreshMode.KeepCurrentValues, item);
18                     db.SubmitChanges();
19                 }
20             }
21         }
22 
23         public static void Detatch<TEntity>(TEntity entity)
24         {
25             Type t = entity.GetType();
26             System.Reflection.PropertyInfo[] properties = t.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
27             foreach (var property in properties)
28             {
29                 string name = property.Name;
30                 if (property.PropertyType.IsGenericType &&
31                 property.PropertyType.GetGenericTypeDefinition() == typeof(EntitySet<>))
32                 {
33                     property.SetValue(entity, null, null);
34                 }
35             }
36             System.Reflection.FieldInfo[] fields = t.GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
37             foreach (var field in fields)
38             {
39                 string name = field.Name;
40                 if (field.FieldType.IsGenericType &&
41                 field.FieldType.GetGenericTypeDefinition() == typeof(EntityRef<>))
42                 {
43                     field.SetValue(entity, null);
44                 }
45             }
46             System.Reflection.EventInfo eventPropertyChanged = t.GetEvent("PropertyChanged");
47             System.Reflection.EventInfo eventPropertyChanging = t.GetEvent("PropertyChanging");
48             if (eventPropertyChanged != null)
49             {
50                 eventPropertyChanged.RemoveEventHandler(entity, null);
51             }
52             if (eventPropertyChanging != null)
53             {
54                 eventPropertyChanging.RemoveEventHandler(entity, null);
55             }
56         }
原文地址:https://www.cnblogs.com/LoveJerryZhang/p/2791838.html