如何使用Linq连接不同的数据源到对象
我需要在运行时使用linq to对象连接不同的数据源,但我的数据源类型未知。所以,我不能直接使用Join。 我有一本包含我的数据源的词典,这就是我所做的:如何使用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
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;
返回动态类型;
}