I have the following LINQ that is causing my obfuscator to break.
.Where(f => f.FileN开发者_JS百科ame == fileName).OrderByDescending(f => f.Position).FirstOrDefault();
Is there another way I could reword this LINQ statement to test against my obfuscator?
I've reported the bug, but it could take 1-2 months to fix, so I need to try recode this LINQ in the meantime.
Update:
The exact cause in the LINQ is :
.Where(f => f.FileName == fileName)
How exactly does the problem manifest? Since the C# expression compiler (used in the LINQ above) uses the memberinfo tokens directly (rather than relying on strings as reflection), I can't see that you could do any better. Likewise, assuming it is an IL obfuscator (not a source obfuscator), re-writing it as a query expression should achieve nothing, nix, zip, zero and nada. You you can try...
var first = (from f in [whatever]
where f.FileName == fileName
orderby f.Position descending
select f).FirstOrDefault();
What exactly happens?
Edit based on comment: if the problem is the "capture", you could try manually building the expression with a constant (instead of a captured value) - where Foo
is your type:
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);
then use:
.Where(predicate).OrderByDescending(f => f.Position).FirstOrDefault();
The problem, of course, is convincing it that "FileName" and Foo.FileName
must stay the same...
And here's a version that doesn't need the string:
Expression<Func<Foo, string>> liftFileName = foo => foo.FileName;
var predicate = Expression.Lambda<Func<Foo, bool>>(
Expression.Equal(liftFileName.Body, Expression.Constant(filename)),
liftFileName.Parameters);
The solution would be to exlcude the .FileName and .Position properties from obfuscation(renaming).
To avoid having to do this on every query, switch to an obfuscator which supports LINQ-to-* such as Crypto Obfuscator.
In the presence of a broken tool, it is impossible to provide a guaranteed fix. You'll have to tinker with it. Try swapping Where
and OrderBy...
. Perhaps FirstOrDefault()
is breaking, so maybe do that part by hand. In fact, even OrderBy...
can probably be replace with a sort. There's a bunch of other stuff you could try.
BTW, Is this LINQ-to-SQL or LINQ-to-Objects? They behave in fundamentally different ways.
Old post, but I had this problem this morning. I'm using .NET Reactor which doesn't natively support obfuscating my POCO's for LINQ to Entities.
If your obfuscator respects the System.Reflection.ObfuscationAttribute
, you can use it to exclude your entities and DbContext from obfuscation.
<Obfuscation(ApplyToMembers:=True, Exclude:=True)>
If you have heavier domain objects with other code that you'd like to obfuscate, the minimum exclusions appear to be:
- DbContext class name
- Property name for each DbSet
- Entity class name
- Mapped entity properties
In these cases, you only have to use the more lightweight form.
<Obfuscation(Exclude:=True)> Public Property ID As Integer
精彩评论