zoukankan      html  css  js  c++  java
  • 关于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         }
  • 相关阅读:
    elk
    js时间处理
    idea首次提交项目
    kafka集群zookeeper集群详细配置
    单节点多节点等等详细解释
    kafka原理存储
    Thread-0" kafka.common.FailedToSendMessageException: Failed to send messages after 3 tries.
    如何使用JMeter开源性能测试工具来构建Web性能测试体系
    自动化测试的理解
    VBS教程
  • 原文地址:https://www.cnblogs.com/LoveJerryZhang/p/2791838.html
Copyright © 2011-2022 走看看