2010-04-29 46 views
2

我有以下LINQ導致我的混淆器中斷。LINQ導致我的混淆器中斷

.Where(f => f.FileName == fileName).OrderByDescending(f => f.Position).FirstOrDefault(); 

是否有另一種方法可以將此LINQ語句重新引用來測試我的混淆器?

我已經報告了錯誤,但可能需要1-2個月才能修復,所以我需要在此期間重新編碼此LINQ。

更新:

在LINQ的確切原因是:

.Where(f => f.FileName == fileName) 

回答

3

究竟如何做的問題清單?由於C#表達式編譯器(在上面的LINQ中使用)使用成員信息令牌直接(而不是依靠字符串作爲反射),我看不出你可以做得更好。同樣,假設它是一個IL混淆器(不是源混淆器),重寫它作爲查詢表達式應該什麼都不會,nix,zip,零和nada。你可以嘗試...

var first = (from f in [whatever] 
      where f.FileName == fileName 
      orderby f.Position descending 
      select f).FirstOrDefault(); 

究竟發生了什麼?


編輯基於註釋:如果問題是「捕獲」,你可以嘗試手動構建表達以恆定的(而不是捕捉值) - 在Foo是你喜歡的類型:

var param = Expression.Parameter(typeof(Foo), "f"); 
    var body = Expression.Equal(Expression.PropertyOrField(param, "FileName"), 
     Expression.Constant(filename)); 
    var predicate = Expression.Lambda<Func<Foo, bool>>(body, param); 

然後使用:

.Where(predicate).OrderByDescending(f => f.Position).FirstOrDefault(); 

的問題,當然是說服它說:「文件名」和Foo.FileName必須保持不變...


下面是不需要的字符串版本:

Expression<Func<Foo, string>> liftFileName = foo => foo.FileName; 
    var predicate = Expression.Lambda<Func<Foo, bool>>(
     Expression.Equal(liftFileName.Body, Expression.Constant(filename)), 
     liftFileName.Parameters); 
+0

當我做一個發佈版本,對於混淆後生成事件失敗,參照未定義類,和另一個錯誤 - 輸入文件的處理過程中「[的SourceFile]」發生錯誤 - > ilasm.exe :警告 - 嵌套類具有非嵌套可見性(0x00000001),更改爲嵌套(0x00000002)。 – 2010-04-29 12:04:50

+0

@JL - 嗯...聽起來像「文件名」捕獲 - 我們*可能*能夠解決這個問題;兩秒鐘... – 2010-04-29 12:06:13

+0

看起來像你的LINQ有與原來相同的問題。完全相同的錯誤。我也決定在集合中做一個快速的空foreach循環,並且表現和編譯。 – 2010-04-29 12:10:48

0

在一個破碎的工具的存在,就不可能提供有保證的修復。你將不得不修補它。嘗試交換WhereOrderBy...。也許FirstOrDefault()正在打破,所以也許手動做那部分。實際上,即使是OrderBy...也可能會被替換。還有其他一些你可以嘗試的東西。

順便說一句,這是LINQ到SQL或LINQ到對象?他們的行爲方式根本不同。

+0

LINQ到對象我想,我正在遍歷一個集合類。 – 2010-04-29 12:12:21

0

解決的辦法是將.FileName和.Position屬性從混淆(重命名)中解放出來。

爲避免在每個查詢中都這樣做,請切換到支持LINQ-to *的混淆器,如Crypto Obfuscator

0

舊帖子,但今天早上我有這個問題。我正在使用.NET Reactor,它本身不支持混淆我的POCO for LINQ to Entities。

如果您的混淆器遵守System.Reflection.ObfuscationAttribute,則可以使用它來將您的實體和DbContext排除在混淆之外。

<Obfuscation(ApplyToMembers:=True, Exclude:=True)> 

如果你有其他較重的碼域對象,你想混淆,最低排除似乎是:

  1. 的DbContext類名
  2. 屬性名稱爲每個DbSet
  3. 實體類名稱
  4. 映射實體屬性

在這些情況下,您只需使用更輕量級的表單。

<Obfuscation(Exclude:=True)> Public Property ID As Integer