如何使用Linq连接不同的数据源到对象

如何使用Linq连接不同的数据源到对象,linq,reflection,linq-to-objects,Linq,Reflection,Linq To Objects,我需要在运行时使用linq to对象连接不同的数据源,但我的数据源类型未知。所以,我不能直接使用Join。 我有一本包含我的数据源的词典,这就是我所做的: public virtual IEnumerable DataSource { get; set; } public virtual void MergeDataSources() { var outerType = System.Type.GetType(DataSources.Keys.First()); DataSou

我需要在运行时使用linq to对象连接不同的数据源,但我的数据源类型未知。所以,我不能直接使用Join。 我有一本包含我的数据源的词典,这就是我所做的:

public virtual IEnumerable DataSource { get; set; }

public virtual void MergeDataSources()
{
    var outerType = System.Type.GetType(DataSources.Keys.First());
    DataSource = Cast(DataSources[DataSources.Keys.First()], outerType);

    foreach (var typeName in DataSources.Keys.Skip(1))
        outerType = Join(outerType, System.Type.GetType(typeName), new[] { "CodigoCliente" }, new[] { "CodigoCliente" });

}

private IEnumerable Cast(IEnumerable datasource, Type type)
{
    return typeof(Enumerable)
                .GetMethod("Cast")
                .MakeGenericMethod(type)
                .Invoke(null, new object[] { datasource }) as IEnumerable;
}

private Type Join(Type outerType, Type innerType, string[] outerKey, string[] innerKey)
{
    var outerKeySelector = GetKeySelector(outerType, outerKey);
    var innerKeySelector = GetKeySelector(innerType, innerKey);

    var resultSelector = Expression.Lambda(
                            null, // <<<<<<------- MISSING!!!
                            Expression.Parameter(outerType),
                            Expression.Parameter(innerType));

    DataSource = typeof(Enumerable)
                    .GetMethod("Join")
                    .MakeGenericMethod(outerType, innerType, typeof(string), typeof(IEnumerable))
                    .Invoke(null, new object[] { DataSource, DataSources[innerType.AssemblyQualifiedName], outerKeySelector, innerKeySelector, resultSelector }) as IEnumerable;

    return null; // <<<<<<------- MISSING!!!
}
公共虚拟IEnumerable数据源{get;set;}
公共虚拟void合并数据源()
{
var outerType=System.Type.GetType(DataSources.Keys.First());
DataSource=Cast(DataSources[DataSources.Keys.First()],outerType);
foreach(数据源中的var typeName.Keys.Skip(1))
outerType=Join(outerType,System.Type.GetType(typeName),new[]{“CodigoCliente”},new[]{“CodigoCliente”});
}
私有IEnumerable强制转换(IEnumerable数据源,类型)
{
返回类型(可枚举)
.GetMethod(“Cast”)
.MakeGenericMethod(类型)
.Invoke(null,新对象[]{datasource})作为IEnumerable;
}
私有类型联接(类型outerType、类型innerType、字符串[]outerKey、字符串[]innerKey)
{
var outerKeySelector=GetKeySelector(outerType,outerKey);
var innerKeySelector=GetKeySelector(innerType,innerKey);
var resultSelector=Expression.Lambda(

null,//您可以使用
Reflection.Emit
动态创建返回类型,请查看此处-

要匹配您的示例,请执行以下操作:

private Type Join(Type outerType, Type innerType, string[] outerKey, string[] innerKey)
{
    var outerKeySelector = GetKeySelector(outerType, outerKey);
    var innerKeySelector = GetKeySelector(innerType, innerKey);

    Dictionary<string, Type> dynamicFields = new Dictionary<string, Type> 
    { 
        { outerType.Name, outerType },
        { innerType.Name, innerType }
    };
    Dictionary<string, ParameterExpression> parameters = new Dictionary<string, ParameterExpression> 
    { 
        { outerType.Name, Expression.Parameter(outerType) },
        { innerType.Name, Expression.Parameter(innerType) }
    };

    Type dynamicType = LinqRuntimeTypeBuilder.GetDynamicType(dynamicFields);

    var resultSelector = Expression.Lambda(
            Expression.MemberInit(
                Expression.New(
                    dynamicType.GetConstructor(Type.EmptyTypes)),
                    dynamicType.GetFields().Select(f => Expression.Bind(f, parameters[f.Name]))),
            parameters.Values)
        .Compile();

    DataSource = typeof(Enumerable)
                    .GetMethods().Where(m => m.Name == "Join" && m.GetParameters().Length == 5).First()
                    .MakeGenericMethod(outerType, innerType, typeof(string), typeof(object))
                    .Invoke(null, new object[] { DataSource, DataSources[innerType.AssemblyQualifiedName], outerKeySelector, innerKeySelector, resultSelector }) as IEnumerable;

    return dynamicType; 
}
私有类型联接(类型outerType、类型innerType、字符串[]outerKey、字符串[]innerKey)
{
var outerKeySelector=GetKeySelector(outerType,outerKey);
var innerKeySelector=GetKeySelector(innerType,innerKey);
Dictionary dynamicFields=新字典
{ 
{outerType.Name,outerType},
{innerType.Name,innerType}
};
字典参数=新字典
{ 
{outerType.Name,Expression.Parameter(outerType)},
{innerType.Name,Expression.Parameter(innerType)}
};
类型dynamicType=LinqRuntimeTypeBuilder.GetDynamicType(dynamicFields);
var resultSelector=Expression.Lambda(
Expression.MemberInit(
新的(
dynamicType.GetConstructor(Type.EmptyTypes)),
dynamicType.GetFields().Select(f=>Expression.Bind(f,参数[f.Name]),
参数(值)
.Compile();
数据源=类型(可枚举)
.GetMethods().Where(m=>m.Name==“Join”&&m.GetParameters().Length==5).First()
.MakeGenericMethod(outerType、innerType、typeof(字符串)、typeof(对象))
.Invoke(null,新对象[]{DataSource,DataSources[innerType.AssemblyQualifiedName],outerKeySelector,innerKeySelector,resultSelector})作为IEnumerable;
返回动态类型;
}