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

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

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

      .NET基礎篇——Entity Framework 數據轉換層通用類

      在實現基礎的三層開發的時候,大家時常會在數據層對每個實體進行CRUD的操作,其中存在相當多的重復代碼。為了減少重復代碼的出現,通常都會定義一個共用類,實現相似的操作,下面為大家介紹一下Entity Framework時常用到的通用類。
      首先在數據庫建立起幾個關聯表:Person、Company、Position,三個實體之間通過導航屬性進行相互引用。

      下面為大家分別介紹以泛型實現的 Create、Read、Update、Delete 操作:

      1. Create

      在ObjectContext類之中,早已經為大家預定了一個Create 的操作 AddObject:

      void ObjectContext.AddObject(entitySetName string,object entity)
      void ObjectSet<T>.AddObject(T entity)

       1          public int Add<T>(T entity) where T : EntityObject
       2          {
       3              int changedCount = 0;
       4              try
       5              {
       6                 using (BasicArchitectureEntities context = new BasicArchitectureEntities())
       7                 {
       8                      context.AddObject(typeof(T).Name, entity);
       9                      changedCount = context.SaveChanges();
      10                      if (changedCount > 0)
      11                          context.AcceptAllChanges();
      12                 }
      13               }
      14               catch (Exception ex)
      15               { ........ }
      16              return changedCount;
      17          }

      從下面的測試可以看到,ObjectContext.AddObject(entitySetName string,object entity)已相當成熟,它不但可以加入單個實體,也可通過導航屬性,一次性加入多個關聯實體。

       1          static void Main(string[] args)
       2          {
       3              BaseCommand command = new BaseCommand();
       4              //建立關聯實體
       5              Company company = new Company() { CompanyName = "Sun" 
       6                     ,Address="Beijing",Telephone="010-87654321"};
       7              Position position = new Position() { PositionName = "Project Manager"
       8                     , Salary = 15000.00, Company = company };
       9              //通過Add<T>同時加入實體對象company與position
      10              int n=command.Add<Position>(position);
      11  
      12              Console.ReadKey();
      13          }

       

      若要使用批量插入,只要在AddObject方法前多加一個重復語言即可,在此就不再多作解釋了。

       1          public int AddList<T>(List<T> entityList) where T : EntityObject
       2          {
       3                  int changedCount = 0;
       4                  try
       5                  {
       6                      using (BasicArchitectureEntities context = new BasicArchitectureEntities())
       7                      {
       8                          foreach (T entity in entityList)
       9                              context.AddObject(typeof(T).Name, entity);
      10                          changedCount = context.SaveChanges();
      11                          if (changedCount > 0)
      12                              context.AcceptAllChanges();
      13                      }
      14                  }
      15                  catch (Exception ex)
      16                  { ....... }
      17                  return changedCount;
      18          }

      2. Delete

      同樣地,ObjectContext 類當中也存在方法 ObjectContext.DeleteObject(object entity)用于刪除實體。
      首先通過輸入的參數 id 建立起EntityKey對象,然后在ObjectContext查找此實體,若實體存在則使用ObjectContext.DeleteObject(object entity)方法把此實體刪除 。

       1           public int Delete<T>(int id) where T : EntityObject
       2           {
       3                   int changedCount = 0;
       4                   try
       5                   {
       6                       using (BasicArchitectureEntities context = new BasicArchitectureEntities())
       7                       {
       8                           //建立EntityKey對象
       9                           EntityKey entityKey = new EntityKey(
      10                                  "BasicArchitectureEntities." + typeof(T).Name, "Id", id);
      11                           //通過EntityKey找到實體
      12                           var objResult = context.GetObjectByKey(entityKey);
      13                           //若實體存在則刪除實體
      14                           if (objResult != null)
      15                               context.DeleteObject(objResult);
      16                           changedCount = context.SaveChanges();
      17                           if (changedCount > 0)
      18                               context.AcceptAllChanges();
      19                       }
      20                   }
      21                   catch (Exception ex)
      22                   { ...... }
      23                   return changedCount;
      24           }

      ObjectContext.DeleteObject(object entity)與ObjectContext.AddObject(entitySetName string,object entity)相同,可以通過導航屬性,一次性刪除多個關聯實體。但如果數據庫中存在下面的數據

      Company表:

      Position表:

       

      此時使用此 int Delete<Company>(2) 方法刪除Company對象,系統將會報錯。這是由于導航屬性在默認情況下具有延時加載的特性,在系統使用ObjectContext.GetObjectByKey(entityKey)方法加載實體時,它的導航屬性不會馬上加載到上下文當中。而是在調用該導航屬性時,對象才會被加載。
      因而系統通過ObjectContext.GetObjectByKey(2)獲取Company對象時,對應的Position對象并未被加載到上下文當中,所以當刪除Company對象時,Position對象不能被同步刪除,因而造成邏輯上的錯誤。為解決這一問題,可以利用RelatedEnd.Load()方法提前加載導航屬性。

      RelatedEnd是EntityCollection<TEntity> 、EntityReference的父類,它們是特定實體類型的對象集合,該實體類型表示一對多、多對一、多對多的關系。而RelatedEnd.Load()方法,可以將一個或多個相關對象提前加載到相關實體當中。

      首先通過ObjectContext.GetObjectByKey(entityKey)方法找到Company對象,然后利用反射屬性PropertyInfo類獲取導航屬性Position,最后使用RelatedEnd.Load()方法,把導航屬性加載到當前上下文中。此時使用Delete<Company,Position>(2)方法刪除Company對象時,系統將能正常運行,并把對應的Position對象一并刪除。

       

       1           public int Delete<PKEntity, FKEntity>(int id)
       2               where PKEntity : EntityObject
       3               where FKEntity : EntityObject
       4           {
       5                   int changedCount = 0;
       6                   try
       7                   {
       8                       using (BasicArchitectureEntities context = new BasicArchitectureEntities())
       9                       {
      10                           //根據軟件Id建立EntityKey對象
      11                           EntityKey entityKey = new EntityKey(
      12                                   "BasicArchitectureEntities." + typeof(PKEntity).Name, "Id", id);
      13                           //根據EntityKey查找對應對象
      14                           PKEntity objResult = context.GetObjectByKey(entityKey) as PKEntity;
      15                           //根據FKEntity加載導航屬性
      16                           PropertyInfo propertyInfo = typeof(PKEntity).GetProperty(
      17                                  typeof(FKEntity).Name);
      18                           EntityCollection<FKEntity> FKEntityList = propertyInfo.GetValue(
      19                                  objResult, null)  as EntityCollection<FKEntity>;
      20   
      21                           if (FKEntityList != null)
      22                               FKEntityList.Load();
      23     
      24                           if (objResult != null)
      25                               context.DeleteObject(objResult);
      26                           changedCount = context.SaveChanges();
      27   
      28                           if (changedCount > 0)
      29                               context.AcceptAllChanges();
      30                       }
      31                   }
      32                   catch (Exception ex)
      33                   { ........ }
      34                   return changedCount;
      35           }

       

      通過下面的方法也可根據輸入的委托predicate,批量刪除有關的數據。

       1          public int Delete<T>(Func<T,bool> predicate) where T: EntityObject
       2          {
       3                  int changedCount = 0;
       4                  try
       5                  {
       6                      using (BasicArchitectureEntities context = new BasicArchitectureEntities())
       7                      {
       8                          //根據輸入的委托查找數據
       9                          var list = context.CreateObjectSet<T>().Where(predicate);
      10                          //若存在數據,刪除有關數據
      11                          if (list.Count() > 0)
      12                              foreach (var obj in list)
      13                                  context.DeleteObject(obj);
      14  
      15                          changedCount = context.SaveChanges();
      16                          if (changedCount > 0)
      17                              context.AcceptAllChanges();
      18                      }
      19                  }
      20                  catch (Exception ex)
      21                  { ...... }
      22                  return changedCount;
      23          }

      與前面的例子相同,當使用 Delete<Company>(x=>x.Id==2) 方法刪除 Company 對象時,由于導航屬性 Position 處于延遲加載的狀態,以致系統無法實現同步刪除,從而令數據出現邏輯性的錯誤。
      此時使用類似的方法,利用 RelatedEnd.Load() 把導航屬性提前加入到上下文中,再刪除Company對象時,系統就可以把對應 Position 對象一并刪除。

       1           public int Delete<PKEntity, FKEntity>(Func<PKEntity,bool> predicate)
       2               where PKEntity : EntityObject
       3               where FKEntity : EntityObject
       4           {
       5                   int changedCount = 0;
       6                   try
       7                   {
       8                       using (BasicArchitectureEntities context = new BasicArchitectureEntities())
       9                       {
      10                           //根據輸入的委托查找數據
      11                           var list = context.CreateObjectSet<PKEntity>().Where(predicate);
      12                           //若數目大于0,刪除有關數據
      13                           if (list.Count() > 0)
      14                           {
      15                               foreach (var obj in list)
      16                               {
      17                                   //在刪除前加載其導航屬性
      18                                   PropertyInfo propertyInfo = typeof(PKEntity)
      19                                          .GetProperty(typeof(FKEntity).Name);
      20                                   EntityCollection<FKEntity> FKEntityList = propertyInfo
      21                                          .GetValue(obj, null) as EntityCollection<FKEntity>;
      22                                  if (FKEntityList.Count > 0)
      23                                       FKEntityList.Load();
      24   
      25                                   context.DeleteObject(obj);
      26                               }
      27                           }
      28                           changedCount = context.SaveChanges();
      29   
      30                           if (changedCount > 0)
      31                               context.AcceptAllChanges();
      32                       }
      33                   }
      34                   catch (Exception ex)
      35                   { ....... }
      36                   return changedCount;
      37           }

      此時使用Delete<Company,Position>(x=>x.Id==2),這樣就可以把Company對象和相關的Position對象同時刪除。

       

      3. Update

      ObjectContext 中存在方法 ObjectContext.ApplyCurrentValues<TEntity> 和 ObjectContext.ApplyOriginalValues<TEntity>,用于把將標量值從實體復制到 ObjectContext 中具有相同主鍵的對象集中。

      注意:在調用此方法前必須把實體預先加載到當前上下文當中,要不然系統將會顯示  “objectstatemanager 無法跟蹤具有相同鍵的多個對象” 的錯誤。

      由于DAL層的對象大部分使用單體模式進行開發,而BaseCommand是一個共用對象,在共同操作時,Create、Delete、Read 等操作一般不會對實體造成邏輯性的影響。但如果有多個實體同時調用 Update 操作,就有可能對實體造成邏輯性影響。為了避免這一事件的發生,此處使用方法鎖定的模式,以 lock(object) 鎖定某一對象,以確保在同一時間內只會對一個實體進行更新。
      首先通過反射方式獲取對象的Id,然后通過 ObjectContext.GetObjectByKey(entityKey) 方法把實體加載到當前上下文當中,最后利用 ObjectContext.ApplyCurrentValues<TEntity> 方法,把新加入的實體的屬性復制當前上下文。

       1      public class BaseCommand
       2      {
       3          private object o = new object();
       4          
       5          public int Update<T>(T entity) where T : EntityObject
       6          {
       7              lock (o)
       8              {
       9                      int changedCount = 0;
      10                      Type type = typeof(T);
      11 
      12                      try
      13                      {
      14                          using (BasicArchitectureEntities context = new BasicArchitectureEntities())
      15                          {
      16                              //獲取實體的Id屬性
      17                              PropertyInfo property = type.GetProperty("Id");
      18                              object id = property.GetValue(entity, null);
      19                              //根據Id獲取上下文中的對應實體
      20                              EntityKey entityKey = new EntityKey("BasicArchitectureEntities." 
      21                                    + type.Name, "Id", id);
      22                              var objResult = context.GetObjectByKey(entityKey);
      23                              //更新實體屬性
      24                              if (objResult != null)
      25                                  context.ApplyCurrentValues<T>(type.Name, entity);
      26  
      27                              changedCount = context.SaveChanges();
      28                              if (changedCount > 0)
      29                                  context.AcceptAllChanges();
      30                          }
      31                      }
      32                      catch (Exception ex)
      33                      { ... }
      34                      return changedCount;
      35              }
      36          }
      37      }

      在一對多,多對一關系時,也可以使用以下方法進行導航屬性的同步更新。首先通過反射獲取主實體的主鍵Id,然后建立EntityKey對象,再通過ObjectContext.GetObjectByKey(entityKey)方法在當前上下文當中獲取此實體,最后通過 ObjectContext.ApplyCurrentValues<TEntity> 方法,把新加入的實體的屬性復制當前上下文。
      下一步就是對導航屬性進行更新,首先通過反射獲取外鍵屬性,然后對一對多,多對一的關系進行分別處理。在一對多關系時,把導航屬性轉換成EntityCollection<T2>對象集合,然后通過 ObjectContext.ApplyCurrentValues<TEntity> 方法對集合中的每個對象進行逐個更新。
      在多對一關系時,直接把導航屬性轉換成T2類型的對象進行更新。

       1          public int Update<T1, T2>(T1 entity)
       2              where T1 : EntityObject
       3              where T2 : EntityObject
       4          {
       5              lock (o)
       6              {
       7                      int changedCount = 0;
       8                      Type typeT1 = typeof(T1);
       9                      Type typeT2 = typeof(T2);
      10                      try
      11                      {
      12                          using (BasicArchitectureEntities context = new BasicArchitectureEntities())
      13                          {
      14                              PropertyInfo property = typeT1.GetProperty("Id");
      15                              object id = property.GetValue(entity, null);
      16  
      17                              //根據軟件Id建立EntityKey對象
      18                              EntityKey entityKey = new EntityKey("BasicArchitectureEntities." 
      19                                   + typeT1.Name, "Id", id);
      20                              //根據EntityKey查找對應對象
      21                              T1 objT1 = context.GetObjectByKey(entityKey) as T1;
      22                              //在上下文中更新當前對象
      23                              if (objT1 != null)
      24                                  context.ApplyCurrentValues<T1>(typeT1.Name, entity);
      25  
      26                              //獲取外鍵屬性
      27                              PropertyInfo propertyInfo = typeT1.GetProperty(typeT2.Name);
      28  
      29                              //在一對多關鍵時更新導航屬性
      30                              var T2List = propertyInfo.GetValue(entity, null) 
      31                                     as EntityCollection<T2>;
      32                              if (T2List != null)
      33                              {
      34                                  foreach (var obj in T2List.ToList())
      35                                  {
      36                                      var oldEntity = context.GetObjectByKey(obj.EntityKey);
      37                                      if (oldEntity != null)
      38                                          context.ApplyCurrentValues<T2>(typeT2.Name, obj);
      39                                  }
      40                              }
      41  
      42                              //在多對一,一對一關系時更新導航屬性
      43                              var objT2 = propertyInfo.GetValue(entity, null) as T2;
      44                              if (objT2!= null)
      45                              {
      46                                  var oldEntity = context.GetObjectByKey(objT2.EntityKey);
      47                                  if (oldEntity != null)
      48                                      context.ApplyCurrentValues<T2>(typeT2.Name, objT2);
      49                              }
      50  
      51                              changedCount = context.SaveChanges();
      52                              if (changedCount > 0)
      53                                  context.AcceptAllChanges();
      54                      }
      55                      catch (Exception ex)
      56                      { ...... }
      57                      return changedCount;
      58              }
      59          }

      通過此方法,無論你要通過Company同步更新Position,還是反過來通過Position同步更新Company,系統也能正常運行。

       

      4. Read

      Read 是CRUD中最常見的,下面就為大家介紹最通用的幾種方法

      4.1 通過Id獲取單個實體

       1         public T GetObject<T>(int id) where T : EntityObject
       2         {
       3             try
       4             {
       5                 using (BasicArchitectureEntities context = new BasicArchitectureEntities())
       6                 {
       7                     EntityKey entityKey = new EntityKey("BasicArchitectureEntities." 
       8                           + typeof(T).Name, "Id", id);
       9                     var objResult = context.GetObjectByKey(entityKey);
      10                     return objResult as T;
      11                 }
      12             }
      13             catch (Exception ex)
      14             {
      15                 return null;
      16             }
      17         }

       

      4.2 通過輸入的Func<T,bool>委托獲取對象

       1         public T GetObject<T>(Func<T,bool> predicate) where T : EntityObject
       2         {
       3             try
       4             {
       5                 using (BasicArchitectureEntities context = new BasicArchitectureEntities())
       6                 {
       7                     var objectSet = context.CreateObjectSet<T>().Where(predicate);
       8                     if (objectSet.Count() > 0)
       9                         return objectSet.First();
      10                     else
      11                         return null;
      12                 }
      13             }
      14             catch (Exception ex)
      15             {
      16                 return null;
      17             }
      18         }

       

      4.3通過輸入的Func<T,bool>委托獲取對象,并同時加載單個導航屬性

       1         public T GetObject<T>(Func<T, bool> predicate,string includePath) 
       2             where T : EntityObject
       3         {
       4             try
       5             {
       6                 using (BasicArchitectureEntities context = new BasicArchitectureEntities())
       7                 {
       8                     var objectQuery = context.CreateObjectSet<T>()
       9                         .Include(includePath)
      10                         .Where(predicate);
      11 
      12                     if (objectQuery.Count() > 0)
      13                         return objectQuery.First();
      14                     else
      15                         return null;
      16                 }
      17             }
      18             catch (Exception ex)
      19             {
      20                 return null;
      21             }
      22         }

       

      4.4通過輸入的Func<T,bool>委托獲取對象,并同時加載多個導航屬性

       1         public T GetObject<T>(Func<T, bool> predicate, string[] includePath)
       2              where T : EntityObject
       3         {
       4             try
       5             {
       6                 using (BasicArchitectureEntities context = new BasicArchitectureEntities())
       7                 {
       8                     var list = context.CreateObjectSet<T>().Where("1==1");
       9 
      10                     foreach (var path in includePath)
      11                         list=list.Include(path);
      12 
      13                     var returnValue = list.Where(predicate).ToList();
      14 
      15                     if (returnValue.Count() > 0)
      16                         return returnValue.First();
      17                     else
      18                         return null;
      19                 }
      20             }
      21             catch (Exception ex)
      22             {
      23                 return null;
      24             }
      25         }

       

      4.5 通過輸入的Func<T,bool>委托獲取對象集合

       1         public IList<T> GetList<T>(Func<T,bool> func) where T:EntityObject
       2         {
       3             try
       4             {
       5                 using (BasicArchitectureEntities context = new BasicArchitectureEntities())
       6                 {
       7                     ObjectSet<T> objectSet = context.CreateObjectSet<T>();
       8                     IList<T> list = objectSet.Where(func).ToList();
       9                     return list;
      10                 }
      11             }
      12             catch (Exception ex)
      13             {
      14                 return null;
      15             }
      16         }

       

      4.6通過輸入的Func<T,bool>委托獲取對象集合,并同時加入單個導航屬性

       1         public IList<T> GetList<T>(Func<T, bool> func,string includePath)
       2              where T : EntityObject
       3         {
       4             try
       5             {
       6                 using (BasicArchitectureEntities context = new BasicArchitectureEntities())
       7                 {
       8                     ObjectSet<T> objectSet = context.CreateObjectSet<T>();
       9                     IList<T> list = objectSet.Include(includePath).Where(func).ToList();
      10                     return list;
      11                 }
      12             }
      13             catch (Exception ex)
      14             {
      15                 return null;
      16             }
      17         }

       

      4.7通過輸入的Func<T,bool>委托獲取對象集合,并同時加入多個導航屬性

       1         public IList<T> GetList<T>(Func<T, bool> func, string[] includePath)
       2             where T : EntityObject
       3         {
       4             try
       5             {
       6                 using (BasicArchitectureEntities context = new BasicArchitectureEntities())
       7                 {
       8                     var list = context.CreateObjectSet<T>().Where("1==1");
       9                     foreach (var path in includePath)
      10                         list = list.Include(path);
      11                     return list.Where(func).ToList();
      12                 }
      13             }
      14             catch (Exception ex)
      15             {
      16                 return null;
      17             }
      18         }

       

      4.8 通過原始的SqlCommandText獲取對象集

       1         public IList<T> GetList<T>(string commandText)
       2         {
       3             try
       4             {
       5                 using (BasicArchitectureEntities context = new BasicArchitectureEntities())
       6                 {
       7                     IList<T> list = context.ExecuteStoreQuery<T>(commandText).ToList();
       8                     return list;
       9                 }
      10             }
      11             catch (Exception ex)
      12             {
      13                 return null;
      14             }
      15         }

      只能完成這一個DAL層的通用類以后,您就可在CompanyDAL、PersonDAL、PositionDAL ...... 等多個類中調用這個通用類,輕松地完成各項CRUD的操作。

       1     public class CompanyDAL:ICompanyDAL
       2     {
       3         private BaseCommand command = new BaseCommand();
       4 
       5         public int AddCompany(Company company)
       6         {
       7             return command.Add<Company>(company);
       8         }
       9 
      10         public int DeleteCompany(int id)
      11         {
      12             return command.Delete<Company>(id);
      13         }
      14 
      15         public int UpdateComapny(Company company)
      16         {
      17             return command.Update<Company>(company);
      18         }
      19         .............
      20     }

      相比起以往的SqlCommand操作,Entity Framework更體現出映射的靈活性。以往的操作中,即使開發出一個通用類,CommandText 通常都需要使用手工輸入,特別是重復的Update命令操作中,往往令人不厭其煩。通過Entity Framework可以把CRUD更高度地集中在一個通用類,令開發變得更加簡單。
      希望本篇文章對您的系統開發有所幫助。

      對軟件架構開發有興趣的朋友歡迎加入博客園討論組 “.NET高級編程”

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

      作者:風塵浪子
      http://www.rzrgm.cn/leslies2/archive/2012/05/16/2504673.html

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






       

      posted on 2012-05-17 14:16  風塵浪子  閱讀(14511)  評論(18)    收藏  舉報

      導航

      主站蜘蛛池模板: 蜜桃一区二区三区免费看| 毛片网站在线观看| 国产成人欧美日本在线观看| 在线观看美女网站大全免费| 最新国内精品自在自线视频| 久久精品人人看人人爽| 中文字幕第一页国产| 国产精品久久久久鬼色| 中文字幕色偷偷人妻久久| 92国产精品午夜福利免费| 浦北县| 99精品国产综合久久久久五月天| 日韩精品亚洲专在线电影| 久久综合九色综合97婷婷| 欧美亚洲色综久久精品国产| 国产精品久久毛片| 玩两个丰满老熟女久久网| 安康市| 国产在线无码精品无码| 91精品国产吴梦梦在线观看永久| 亚洲精品一区二区麻豆| 99在线精品视频观看免费| 91区国产福利在线观看午夜| 国产欧美日韩亚洲一区二区三区 | 亚洲AV无码久久精品日韩| 少妇厨房愉情理9仑片视频| 日韩av天堂综合网久久| 日日碰狠狠躁久久躁96avv| 亚洲自在精品网久久一区| 91中文字幕在线一区| 久久精品人妻少妇一区二| 中文字幕亚洲精品人妻| 成人精品天堂一区二区三区| 亚洲中文字幕一区精品自| 亚洲AV无码破坏版在线观看| 成人伊人青草久久综合网| 二区中文字幕在线观看| 国产不卡一区二区四区| 久久大香萑太香蕉av黄软件| 国产91精品丝袜美腿在线| 欧美xxxxhd高清|