<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      .NET基礎篇——利用泛型與反射更新實體(ADO.NET Entity Framework)

       

      自從ADO.NET Entity Framework面世以來,受到大家的熱捧,它封裝了大量代碼生成的工具,用戶只需要建立好實體之間的關系,系統就是會為用戶自動成功了Add、Delete、CreateObject、Attach、ToList......等等方法,這些方法基本上已經包含獲取、刪除、插入等基本方法,使用起來非常方便。只是在實體的更新上,由于LINQ面向的是泛型對象T,所以每個對象的更新方法都要由用戶自動編輯。有見及此,下面在下利用反射方法,創建了一個更新工具,此工具可以更新ObjectContext里面的任意一個實體或者多個關聯實體。

       

       一、簡單介紹反射

      反射是一個程序集發現及運行的過程,通過反射可以得到*.exe或*.dll等程序 集內部的信息。使用反射可以看到一個程序集內部的接口、類、方法、字段、屬性、特性等等信息。在System.Reflection命名空間內包含多個反 射常用的類,下面表格列出了常用的幾個類。(詳細的資料請參考“反射的奧妙”)

      類型 作用
      Assembly 通過此類可以加載操縱一個程序集,并獲取程序集內部信息
      EventInfo 該類保存給定的事件信息
      FieldInfo 該類保存給定的字段信息
      MethodInfo 該類保存給定的方法信息
      MemberInfo 該類是一個基類,它定義了EventInfo、FieldInfo、MethodInfo、PropertyInfo的多個公用行為
      Module 該類可以使你能訪問多個程序集中的給定模塊
      ParameterInfo 該類保存給定的參數信息      
      PropertyInfo 該類保存給定的屬性信息

       

       

      二 、實體與上下文的關系

      每個實體值都會包含在上下文中, 當您從客戶端回收到實體時, 可以比較與上下文中的該實體的版本更新的實體,并應用適當的更改。值得注意的是,上下文會必須KEY找到實體對像,然后對每一個屬性逐個賦值。如果想對實體對象直接賦值,那么KEY那將會改變,系統將無法從上下文中找到該對象。

       

       

      三、開發實例

      在為一個項目建立關系圖時,都會為多個實體建立關系,在更新實體時往往需要把導航屬性一同更新,這使得更新方法更為繁瑣。比如在覺見的訂單管理項目中,在更新訂單Order的同時,必須把訂單對應的OrderItem對象實現同步更新。為了簡化代碼,在下利用反射原理建立一個了特定類UpdateHelp,利用這個類可以更新ObjectContext里面的多個關系對象。

      其原理在于系統使用GetIntrinsicObj(EntityObject)方法,根據輸入實體(obj)的KEY在上下文中獲取對應的實體對象(intrinsic),然后使用UpdateIntrinsticObj(Object)方法,利用PropertyInfo遍歷實體的每個屬性,把輸入的實體對象(obj)的每個屬性都賦值給上下文的實體對象(intrinsic)。最特別的地方在于當遇到導航屬性的時候,使用了遞歸算法,重復調用UpdateIntrinsticObj(object)方法為導航屬性賦值。當遇到一對多或者多對多關系的時候,導航屬性將會是是一個List<T>對象,方法中CloneNavigationProperty是為單個對象賦值,而CloneNavigationPropertyEntityCollection方法是為多個對象賦值。

           public class UpdateHelp:IDisposable
      {
      //記錄已經復制過的實體類,避免重復加載
      private IList<Type> listType = new List<Type>();
      private BusinessContext _context;

      public UpdateHelp(BusinessContext context)
      {
      _context = context;
      }

      public void Dispose()
      {
      _context.Dispose();
      }

      //更新普通屬性
      private void CloneProperty(PropertyInfo propertyInfo,object intrinsicObj,object newObj)
      {
      var data = propertyInfo.GetValue(newObj, null);
      propertyInfo.SetValue(intrinsicObj, data, null);
      }

      //更新普通導航屬性
      private void CloneNavigationProperty(PropertyInfo propertyInfo,object intrinsicObj,object newObj)
      {
      var data = propertyInfo.GetValue(newObj, null);
      object dataClone = UpdateIntrinsticObj(data);
      propertyInfo.SetValue(intrinsicObj, dataClone, null);
      }

      //更新返回值為集合EntityCollection<TEntity>的導航屬性
      private void CloneNavigationPropertyEntityCollection(PropertyInfo propertyInfo, object intrinsicObj, object newObj)
      {
      //獲取參數newObj中的對象集合
      IEnumerable<object> newData = propertyInfo.GetValue(newObj, null) as IEnumerable<object>;
      //獲取上下文中匹配的原對象集合
      var intrinsicData = propertyInfo.GetValue(intrinsicObj, null);
      //利用EntityCollection<TEntity>類的擴展方法Add在原集合中加入新對象
      var addMethod = intrinsicData.GetType().GetMethod("Add");
      foreach (object obj in newData)
      {
      Object objClone = UpdateIntrinsticObj(obj);
      addMethod.Invoke(intrinsicData, new object[] { objClone });
      }
      }

      //獲取上下文中待更新的原對象
      private object GetIntrinsicObj(EntityObject entity)
      {
      Object intrinsicObj;
      //根據輸入對象的EntityKey判斷該對象是已有值還是新建值
      //若是已有值即從上下文中獲取對應值,若是新建值即反射生成一個新對象
      if (entity.EntityKey.EntityKeyValues != null)
      intrinsicObj = _context.GetObjectByKey(entity.EntityKey);
      else
      intrinsicObj = Activator.CreateInstance(entity.GetType());

      return intrinsicObj;
      }

      //更新上下文中的原對象,返回值為更新后的原對象
      public object UpdateIntrinsticObj(Object obj)
      {
      //記錄已經復制過的實體類,避免重復加載
      listType.Add(obj.GetType());
      //獲取上下文中的原對象
      Object intrinsicObj=GetIntrinsicObj(obj as EntityObject);
      //更新原對象的每個一個屬性
      //把原對象intrinsicObj的每一個屬性設置為與obj對象相等
      foreach (PropertyInfo propertyInfo in obj.GetType().GetProperties())
      {
      //若listType里面包含些類型,證明此實體類已經更新過
      if (!listType.Contains(propertyInfo.PropertyType) && propertyInfo.CanWrite
      && propertyInfo.Name != "EntityKey"&& propertyInfo.PropertyType.Name != "EntityReference`1")
      {
      //若為導航屬性則需要使用此方法更新
      if (propertyInfo.GetCustomAttributes(typeof(EdmRelationshipNavigationPropertyAttribute), false).Count() != 0)
      {
      //若導航屬性返回值為集合則使用此方法
      if (propertyInfo.PropertyType.Name == "EntityCollection`1")
      CloneNavigationPropertyEntityCollection(propertyInfo, intrinsicObj, obj);
      else//若導航屬性為普通對象則使用以下方法
      CloneNavigationProperty(propertyInfo, intrinsicObj, obj);
      }
      else //若為普通屬性則使用以下方法
      CloneProperty(propertyInfo, intrinsicObj, obj);
      }
      }
      return intrinsicObj;
      }
      }

      在完成更新操作后,再加上LingHelp類,就可以利用它完成大部的數據處理問題,大家可以建立main測試一下。

          public class LinqHelp:IDisposable
      {
      private BusinessContext _context;
      private UpdateHelp _updateHelp;

      public LinqHelp()
      {
      _context = new BusinessContext();
      _updateHelp = new UpdateHelp(_context);
      }

      public LinqHelp(BusinessContext context)
      {
      _context = context;
      _updateHelp = new UpdateHelp(context);
      }

      public void Dispose()
      {
      _context.Dispose();
      }

      public int Add<T>(T entity) where T : EntityObject
      {
      int n = -1;
      Transaction transaction = Transaction.Current;
      try
      {
      _context.AddObject(entity.GetType().Name, entity);
      n = _context.SaveChanges();
      }
      catch (Exception ex)
      {
      Business.Common.ExceptionManager.DataException.DealWith(ex);
      transaction.Rollback();
      }
      return n;
      }

      public int Update<T>(ref T entity) where T:EntityObject
      {
      int n = -1;
      Transaction transaction = Transaction.Current;
      try
      {
      EntityObject returnObj = this._updateHelp.UpdateIntrinsticObj(entity) as EntityObject;
      n = _context.SaveChanges();
      entity = _context.GetObjectByKey(entity.EntityKey) as T;
      }
      catch (Exception ex)
      {
      Business.Common.ExceptionManager.DataException.DealWith(ex);
      transaction.Rollback();
      }
      return n;
      }

      public List<T> GetList<T>(string name) where T:EntityObject
      {......}
      ........
      }

      public class OrderRepository
      {
      private LinqHelp _linqHelp;

      public OrderRepository()
      {
      _linqHelp = new LinqHelp();
      }

      public int AddOrder(Order order)
      {..........}

      ..............

      public int UpdateOrder(Order order)
      {
      return _linqHelp.Update<Order>(ref order);
      }
      }
          public class PersonRepository
      {......}

      class Program
      {
      static void Main(string[] args)
      {
      Test1();
      Console.ReadKey();
      }

      public static void Test1()
      {
      using (BusinessContext context = new BusinessContext())
      {
      context.ContextOptions.LazyLoadingEnabled = true;
      var order = context.Order.First();
      order.Person.Address = "北京路1號";
      OrderRepository orderRepository = new OrderRepository();
      orderRepository.UpdateOrder(order);
      }
      }

              public static void Test2()
              {
                  using (BusinessContext context = new BusinessContext())
                  {
                      Person person = context.Person.First();
                      Order order = new Order();
                      order.OrderNumber = "2A34313344";
                      OrderItem orderItem = new OrderItem();
                      orderItem.Goods = "555";
                      orderItem.Count = 8;
                      orderItem.Price = 2.5;
                      order.OrderItem.Add(orderItem);
                      person.Order.Add(order);

                      PersonRepository personRepository = new PersonRepository();
                      personRepository.UpdatePerson(person);
                      Console.Write(person.Order.First().ID + person.Order.First().OrderItem.First().ID);
                  }
              }
      }

       

      四、性能問題

      由于過度使用反射會使系統的性能下降,所以需要注意此更新方法的使用范圍。一般此反射更新只會使用在小型的項目當中,如果在大中型項目內使用,將會在性能上負出代價。由于時間有限,而且沒有經過大量的測試,有不足之處請點評。

      對.NET開發有興趣的朋友請加入博客園討論小組“.NET高級編程” 一起探討!

      對 .NET  開發有興趣的朋友歡迎加入QQ群:162338858 共同探討 ! 

       

      .NET基礎篇

      以異步的方式操作TCP/IP套接字——以異步方式實現簡單的聊天室
      合理使用“.NET擴展方法”來簡化代碼(例子:空值判斷,利用擴展方法實現LINQ操作符ForEach)
      分部類和分部方法
      反射的奧妙
      利用泛型與反射更新實體(ADO.NET Entity Framework)

      作者:風塵浪子

      http://www.rzrgm.cn/leslies2/archive/2011/11/24/2257572.html

      原創作品,轉載時請注明作者及出處

       

      posted on 2011-11-24 15:15  風塵浪子  閱讀(14366)  評論(16)    收藏  舉報

      導航

      主站蜘蛛池模板: 国产av亚洲精品ai换脸电影| 久久这里有精品国产电影网| 成人中文在线| 精品无码老熟妇magnet| 亚洲国产熟女一区二区三区| 福利成人午夜国产一区| 中文在线а√天堂| 日韩美少妇大胆一区二区| 国产粉嫩美女一区二区三| 免费看欧美全黄成人片| 欧洲免费一区二区三区视频| 亚洲av成人网人人蜜臀| 日本一本正道综合久久dvd| 国产激情无码一区二区三区| 精品福利视频一区二区三区| 亚洲国产精品综合色在线| 中文字幕国产精品综合| 无码国产偷倩在线播放| 性欧美乱熟妇xxxx白浆| 日本国产一区二区三区在线观看| 中文字幕亚洲精品第一页| 久久青草国产精品一区| 国产精品久久久久久久久久直播| 和政县| 高清中文字幕一区二区| 中文熟妇人妻av在线| 欧美白妞大战非洲大炮| 激情动态图亚洲区域激情| 亚洲中文字幕无码中文字| 国产精品无遮挡又爽又黄| 国产高清一区二区不卡| 国产精品视频亚洲二区| 日本视频一两二两三区| 鲁一鲁一鲁一鲁一澡| 国产精品久线在线观看| 国产亚洲精品在av| 噜妇插内射精品| 中文字幕一区二区三区麻豆| 少妇熟女久久综合网色欲| 国产女人喷潮视频免费| 久久国内精品自在自线91|