国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

【分享】基于LINQ TO SQL的多層架構中,如何將實體附加至不同的DataContext

2019-11-17 03:51:54
字體:
來源:轉載
供稿:網友
注意:

     1.本文中所提到的“實體”均為由LINQ TO SQL生成的(即.dbml)

     2.你需要了解LINQ TO SQL對表關聯的實現方式,EntitySet 和 EntityRef

     也許你看到標題后,會覺得問題比較抽象,那么我舉個實例來具體說明一下問題。



      在基于LINQ TO SQL的N層架構中,假如我們需要對一個實體進行更新,那么流程應是這樣:



流程


BLL.GetModel(p=>p.id==1) --> 修改相應屬性(字段)值 --> BLL.Update(Entity entity) --> DAL.Update(Entity entity) --> 更新成功



     此時,我們需要將這個實體從業務層(BLL)傳遞到數據訪問層(DAL),當GetModel方法返回實體后會立即釋放掉DataContext,然后到了執行DAL.Update(Entity entity)方法時又重新實例化一個DataContext來進行更新操作;可見被傳遞的實體是從第一個DataContext傳遞到另一個DataContext,在LINQ TO SQL中這種跨越不同DataContext操作時,需要先進行附加操作,也就是context.Entity.Attach(entity,true); 最后再context.SubmitChanges();



還是看看代碼吧:



代碼
class BLL
{
  PRivate readonly DAL dal = new DAL();
  public LinqToSqlProvider.User GetModel(Expression<Func<LinqToSqlProvider.User, bool>> expression)
{
   dal.GetModel(expression);
}
  public void Update(LinqToSqlProvider.User entity)
  {
     dal.Update(entity);
  }
}

class DAL
{
        
        public LinqToSqlProvider.User GetModel(Expression<Func<LinqToSqlProvider.User, bool>> expression)
        {
            LinqToSqlProvider.User entry = new CriTextBroadcast.LinqToSqlProvider.User();
            using (CriTextBroadcastDBDataContext context = DataContext)
            {
                entry =  context.User.SingleOrDefault(expression);
            }
            return entry;
        }

        public void Update(LinqToSqlProvider.User entity)
        {
           using (CriTextBroadcastDBDataContext context = DataContext)
            {
                context.User.Attach(entry, true);
                context.SubmitChanges();
            }
        }
}


實際我們用以上代碼操作時,會出現此異常:

已嘗試 Attach 或 Add 實體,該實體不是新實體,可能是從其他 DataContext 中加載來的......



      查了N多資料未果,后來還是在一國外的帖子里看到了類似問題。原來是這個實體對應的表有若干個關聯表,如:User -> Message ,User -> Images等,

在生成實體類時會自動產生:EntitySet<Message> Message這樣的屬性,由于我們在獲取實體時并未將這些關聯的內容一起讀出來,而在附加時(Attach)這些屬性便會出現ObjectDisposedException異常,也就是因為之前查詢這個實體時的DataContext已經釋放掉了導致的。



解決方法:



代碼
/// <summary>
        /// 輔助LinqToSql實體與原DataContext分離
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="entity"></param>
        public static void Detatch<TEntity>(TEntity entity)
        {

            Type t = entity.GetType();

            System.Reflection.PropertyInfo[] properties = t.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);

            foreach (var property in properties)
            {

                string name = property.Name;

                if (property.PropertyType.IsGenericType &&

                property.PropertyType.GetGenericTypeDefinition() == typeof(EntitySet<>))
                {

                    property.SetValue(entity, null, null);

                }

            }

            System.Reflection.FieldInfo[] fields = t.GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);

            foreach (var field in fields)
            {

                string name = field.Name;

                if (field.FieldType.IsGenericType &&

                field.FieldType.GetGenericTypeDefinition() == typeof(EntityRef<>))
                {

                    field.SetValue(entity, null);

                }

            }

            System.Reflection.EventInfo eventPropertyChanged = t.GetEvent("PropertyChanged");

            System.Reflection.EventInfo eventPropertyChanging = t.GetEvent("PropertyChanging");

            if (eventPropertyChanged != null)
            {

                eventPropertyChanged.RemoveEventHandler(entity, null);

            }

            if (eventPropertyChanging != null)
            {

                eventPropertyChanging.RemoveEventHandler(entity, null);

            }

        }


應在獲得實體后使用Detach(entity)方法將實體與原DataContext分離,然后再附加(Attach)到新的DataContext中去


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 清原| 会昌县| 凤翔县| 沐川县| 沽源县| 绥阳县| 独山县| 年辖:市辖区| 昭平县| 民丰县| 云南省| 巩义市| 潢川县| 大石桥市| 平泉县| 谷城县| 翼城县| 波密县| 平原县| 凉城县| 富源县| 中西区| 丰城市| 原阳县| 永善县| 仁怀市| 临武县| 竹溪县| 永州市| 土默特右旗| 内丘县| 嘉善县| 南城县| 黄大仙区| 玉山县| 鄢陵县| 东乌| 鄱阳县| 阜城县| 驻马店市| 米易县|