2009-06-18 170 views
1

當使用linq刪除記錄時,我有一個奇怪的問題,我懷疑它與範圍變量(名爲source)有關。刪除記錄後爲客戶所有目標都使用下面的語句檢索:linq'範圍變量'問題

var q = from source in unitOfWork.GetRepository<db_Target>().Find() 
    where source.db_TargetBase.db_Person.fk_Customer == customerID 
    select source.FromLinq(); 

其中FromLinq是extention方法上db_target:

public static Target FromLinq(this db_Target source) 
{ 
    return new Target 
    { 
     id = source.id, 
     LastModified = source.db_TargetBase.LastModified, 
     ... 
    } 
} 

當一條記錄被刪除既db_Targetdb_TargetBase被刪除。例如,當兩個用戶正在刪除記錄時,linq會嘗試檢索由user1刪除的user2的記錄,導致LastModified = source.db_TargetBase.LastModified行發生崩潰,因爲db_TargetBasenull

使用下面的代碼問題不occure,只有非刪除的記錄檢索:

var q = from source in unitOfWork.GetRepository<db_Target>().Find() 
    where source.db_TargetBase.db_Person.fk_Customer == customerID 
    select new Target 
    { 
     id = source.id, 
     LastModified = source.db_TargetBase.LastModified, 
     ... 
    }; 

這會生成兩個問題:

  1. 這到底是怎麼回事?我是否正在製作範圍變量source的副本,因爲我在擴展方法中使用它?
  2. 如何「包裝」return new Target代碼?我在多個地方使用它,不想每次都複製它。使我的代碼難以維護。

TIA,

JJ

回答

1

在第一組的代碼 - 由於初始化住的一個不可翻譯方法(擴展或以其他方式),它不能被翻譯 - 因此它在本地運行。

在第二組代碼中,初始值設定項由一個elementinit表達式表示,它被翻譯(檢查/比較生成的sql的select子句以進行證明)。


,如果你想換這個,你需要有一個Expression<Func<db_Target, Target>>,任何人都可以搶在thier查詢中使用。幸運的是,這很容易做到:

public Expression<Func<db_Target, Target>> GetFromLinqExpressionForTarget() 
{ 
    return 
    source => new Target 
    { 
     id = source.id, 
     LastModified = source.db_TargetBase.LastModified, 
     ... 
    } 
} 

可以使用像這樣:

var FromLinq = GetFromLinqExpressionForTarget(); 
var q = 
(
    from source in ... 
    ... 
    ... 
    select source 
).Select(FromLinq); 

現在......我真的在猜運行在這裏和我只有60%左右有信心,我的答案是正確的。所以如果有人想證實這一點,那會讓我有一天。 :)

+0

感謝您的回覆,您的解釋對我來說非常有意義。 但是,現在我正在度假,當我有時間的時候我會測試實施並給出適當的反饋。 – user124936 2009-06-21 21:40:17