Click here to Skip to main content
15,885,998 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more: , +
Hi.
I have a method that generate Entityframework include dynamiclly from an object and build string that look like this:
"x=> x.Connectors , x=> x.BlockEntryFieldsGroup.Select(GhIm=> GhIm.BlockEntry_Field.Select(GhImcc=> GhImcc.BlockEntry_Value)) , x=> x.BlockEntryOffSet"


and i would like to convert the given string to params Expression>[] includes right now i use
C#
CSharpCodeProvider
to dynamilcy convert it.

is there any better way to do this without using
C#
CSharpCodeProvider


What I have tried:

this is what i do right now.
 var searchValue = DynamicIncludeExpressionString(typeof(T), "x");
    if (!searchValue.Any())
        return source;
    var func = "x=> " + string.Join(" , x=> ", searchValue);
    var builder = new StringBuilder();
    builder.Append("\r\nusing System;");
    builder.Append("\r\nusing System.Collections.Generic;");
    builder.Append("\r\nusing System.Linq;");
    builder.Append("\r\nusing System.Reflection;");
    builder.Append("\r\nusing SourceTech.Core.Interface;");
    builder.Append("\r\nusing SourceTech.Core.ObjectLibrary;");
    builder.Append("\r\nusing SourceTech.Core.Expression;");
    builder.Append("\r\nnamespace DynamicLinqInclude");
    builder.Append("\r\n{");
    builder.Append("\r\npublic sealed class Dynamic_LinqInclude");
    builder.Append("\r\n{");
    builder.Append("\r\npublic static IQueryable<" + type.FullName + "> Execute<T>(IQueryable<" + type.FullName + "> source)");
    builder.Append("\r\n{");
    builder.Append("\r\n return source.IncludeEntitys(" + func + ");");
    builder.Append("\r\n}");
    builder.Append("\r\n}");
    builder.Append("\r\n}");
    var codeProvider = new CSharpCodeProvider();
    var compilerParameters = new CompilerParameters
    {
        GenerateExecutable = false,
        GenerateInMemory = false,
        CompilerOptions = "/optimize"
    };
    compilerParameters.ReferencedAssemblies.Add("System.dll");
    compilerParameters.ReferencedAssemblies.Add(typeof(System.Linq.IQueryable).Assembly.Location);
    compilerParameters.ReferencedAssemblies.Add(typeof(System.Collections.IList).Assembly.Location);
    compilerParameters.ReferencedAssemblies.Add(typeof(System.Linq.Enumerable).Assembly.Location);
    compilerParameters.ReferencedAssemblies.Add(typeof(T).Assembly.Location);
    string sourceCode = builder.ToString();
    CompilerResults compilerResults = codeProvider.CompileAssemblyFromSource(compilerParameters, sourceCode);
    Assembly assembly = compilerResults.CompiledAssembly;
    Type types = assembly.GetType("DynamicLinqInclude.Dynamic_LinqInclude");
    MethodInfo methodInfo = types.GetMethod("Execute");
    methodInfo = methodInfo.MakeGenericMethod(type);
    if (!DynamicLinqIncludeSources.ContainsKey(key)) // it may have been added by another threads
    {
        DynamicLinqIncludeSources.Add(key, methodInfo); // Save it in a temp instead of memory so we could choose to Clear it later.
        DynamicLinqIncludeSourceLength++;
    }
}

return (IQueryable<T>)DynamicLinqIncludeSources[key].Invoke(null, new object[] { source });
Posted
Updated 4-Jun-17 6:58am

1 solution

It may be easier and cleaner to wrap IQueryable<t> provided by DbContext.Set<t>() instead of produce a string to parse by compiler. Indeed you can take advantage by using expression tree and not required Codedom.
 
Share this answer
 
Comments
Alen Toma 5-Jun-17 13:59pm    
Well! would you be kind and provide an example please?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900