Hallo,
wir verwenden in unserer Applikation Roslyn um dynamisch Code zu kompilieren...
Nun bekomme ich bei folgender Klasse:
using MCC.Common.ServiceInterfaces.DTO.CacheableQuery;
using MCC.VISU.DL;
using MCC.VISU.Services.VisuServiceInterfaces.DTO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Globalization;
using LinqToDB;
using System.Linq.Dynamic.Core;
namespace CachableQuery
{
public class REPORT_SrmStatictisQuery : ICachableQueryScript
{
public object Run(object[] parameters)
{
DateTime @from = DateTime.Now; // (DateTime)parameters[0];
DateTime to = DateTime.Now; //(DateTime)parameters[1];
using (var db = new VisuDb())
{
var retVal = new List<Data>();
var tagsQry = db.Tags.Where(x => Sql.Like(x.Name, "SRM.%.ServiceData.%"));
var p = Expression.Parameter(typeof(TagDTO));
if (parameters[2] != null)
{
var srmNames = ((string)parameters[2]).Split(',');
Expression e = Expression.Call(Expression.Property(p, "Name"), typeof(string).GetMethods().First(x => x.Name == "StartsWith" && x.GetParameters().Length == 1), Expression.Constant("SRM." + srmNames[0] + ".ServiceData."));
foreach (var nm in srmNames.Skip(1))
{
e = Expression.Or(e, Expression.Call(Expression.Property(p, "Name"), typeof(string).GetMethods().First(x => x.Name == "StartsWith" && x.GetParameters().Length == 1), Expression.Constant("SRM." + nm + ".ServiceData.")));
}
tagsQry = tagsQry.Where(Expression.Lambda<Func<TagDTO, bool>>(e, p));
}
....
return retVal;
}
}
}
}
den Fehler:
Fehlermeldung:
: "REPORT_SrmStatictisQuery.cs(66,45): error CS1503: Argument 2: cannot convert from 'System.Linq.Expressions.Expression<System.Func<MCC.VISU.Services.VisuServiceInterfaces.DTO.TagDTO, bool>>' to 'System.Func<MCC.VISU.Services.VisuServiceInterfaces.DTO.TagDTO, bool>'"
Problem ist, in Visual STudio kann er die Klasse ohne Probleme übersetzen. Aber irgendwie findet er die Implementierung in der Queryable Klasse nicht wenn ich Roslyn selber starte.
Als wir Roslyn noch aus dem Net-Framework 4.8 aufgerufen haben hat das so funktioniert. Seit wir nun auf netcore 6 sind geht es nicht mehr...
Mein Roslyn Aufruf sieht ungefähr so aus:
var st = SourceText.From(code.ToStream(), Encoding.UTF8, canBeEmbedded: true);
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(st,
new CSharpParseOptions(kind: SourceCodeKind.Regular, languageVersion: LanguageVersion.Latest), path: codefileName);
string assemblyName = Path.GetRandomFileName();
var emitOptions = new EmitOptions(debugInformationFormat: DebugInformationFormat.PortablePdb );
var embeddedTexts = new[] { EmbeddedText.FromSource(syntaxTree.FilePath, syntaxTree.GetText()) };
var references = new List<MetadataReference>()
{
MetadataReference.CreateFromFile(AssemblyLoader.AssemblyLoader.GetAssemblyPath(systemCollectionsAssembly)),
MetadataReference.CreateFromFile(AssemblyLoader.AssemblyLoader.GetAssemblyPath(systemRuntimeAssembly)),
MetadataReference.CreateFromFile(AssemblyLoader.AssemblyLoader.GetAssemblyPath(netstandardAssembly)),
MetadataReference.CreateFromFile(AssemblyLoader.AssemblyLoader.GetAssemblyPath(systemComponentModelAssembly)),
MetadataReference.CreateFromFile(AssemblyLoader.AssemblyLoader.GetAssemblyPath(typeof(object).Assembly)),
....
};
if (neededAssemblys != null)
{
foreach (var neededAssembly in neededAssemblys)
{
references.Add(MetadataReference.CreateFromFile(AssemblyLoader.AssemblyLoader.GetAssemblyPath(neededAssembly)));
}
}
var compilation = CSharpCompilation.Create(
assemblyName,
syntaxTrees: new[] { syntaxTree },
references: references,
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary,
optimizationLevel: OptimizationLevel.Debug));
using (var ms = new MemoryStream())
using (var msPDB = new MemoryStream())
{
EmitResult result = compilation.Emit(ms, pdbStream: msPDB, options: emitOptions, embeddedTexts: embeddedTexts);
hat jemand ne idee?
cSharp Projekte : https://github.com/jogibear9988
NUn gehts...
const string systemLinqQueryableName = "System.Linq.Queryable";
var systemLinqQueryableAssembly = Assembly.Load(systemLinqQueryableName);
MetadataReference.CreateFromFile(AssemblyLoader.AssemblyLoader.GetAssemblyPath(systemLinqQueryableAssembly)),
cSharp Projekte : https://github.com/jogibear9988