C#-选择实体和变量LINQ/query
我正在使用C#构建一个文件下载服务——该过程的一部分是验证从一个或多个数据库下载的内容,并提供下载的详细信息 验证过程可以调用四个数据库——这实际上取决于下载的服务。数据库是MSSQL或MySQL,可以使用存储过程(复杂类型)或具有多个联接的LINQ查询。所有结果将包含相同的列信息 我已经在Entity框架中定义了数据库,我对单个实例中的代码很满意——如果我查询不同的数据库,我不想再次编写执行相同任务的代码 我已经搜索了几个小时,试图找到一个解决方案,使我能够根据条件指定要使用的实体和查询,并使其保持强类型 对于存储过程查询,我使用如下代码:C#-选择实体和变量LINQ/query,c#,entity-framework-4.1,C#,Entity Framework 4.1,我正在使用C#构建一个文件下载服务——该过程的一部分是验证从一个或多个数据库下载的内容,并提供下载的详细信息 验证过程可以调用四个数据库——这实际上取决于下载的服务。数据库是MSSQL或MySQL,可以使用存储过程(复杂类型)或具有多个联接的LINQ查询。所有结果将包含相同的列信息 我已经在Entity框架中定义了数据库,我对单个实例中的代码很满意——如果我查询不同的数据库,我不想再次编写执行相同任务的代码 我已经搜索了几个小时,试图找到一个解决方案,使我能够根据条件指定要使用的实体和查询,并使
using (myEntity1 ctx = new myEntity1())
{
var results = ctx.MyStoredProcedure(param1, param2);
foreach (var result in results)
{
// do stuff here
}
}
using (myEntity2 ctx = new myEntity2())
{
var results = (from t in ctx.table select new { t.Col1, t.Col2,});
foreach (var result in results)
{
// do stuff here
}
}
对于LINQ查询,我可以使用如下代码:
using (myEntity1 ctx = new myEntity1())
{
var results = ctx.MyStoredProcedure(param1, param2);
foreach (var result in results)
{
// do stuff here
}
}
using (myEntity2 ctx = new myEntity2())
{
var results = (from t in ctx.table select new { t.Col1, t.Col2,});
foreach (var result in results)
{
// do stuff here
}
}
简而言之,我希望能够基于许多条件指定实体和查询。我还希望结果是强类型的。这似乎很简单,但我找不到有效的答案
谢谢
Chris经过一年不间断的学习,如果我现在这样做,我可能会使用存储库将每个数据集加载到其POCO中,然后将这些POCO投影到我真正想要的POCO中,可能会使用以下扩展方法:
public static class QueryableExtensions
{
public static ProjectionExpression<TSource> Project<TSource>(this IQueryable<TSource> source)
{
return new ProjectionExpression<TSource>(source);
}
public static string GetSQL<TSource>(this IQueryable<TSource> source)
{
return source.ToString();
}
}
public class ProjectionExpression<TSource>
{
private static readonly Dictionary<string, Expression> ExpressionCache = new Dictionary<string, Expression>();
private readonly IQueryable<TSource> _source;
public ProjectionExpression(IQueryable<TSource> source)
{
_source = source;
}
public IQueryable<TDest> To<TDest>()
{
var queryExpression = GetCachedExpression<TDest>() ?? BuildExpression<TDest>();
return _source.Select(queryExpression);
}
private static Expression<Func<TSource, TDest>> GetCachedExpression<TDest>()
{
var key = GetCacheKey<TDest>();
return ExpressionCache.ContainsKey(key) ? ExpressionCache[key] as Expression<Func<TSource, TDest>> : null;
}
private static Expression<Func<TSource, TDest>> BuildExpression<TDest>()
{
var sourceProperties = typeof(TSource).GetProperties();
var destinationProperties = typeof(TDest).GetProperties().Where(dest => dest.CanWrite);
var parameterExpression = Expression.Parameter(typeof(TSource), "src");
var bindings = destinationProperties
.Select(destinationProperty => BuildBinding(parameterExpression, destinationProperty, sourceProperties))
.Where(binding => binding != null);
var expression = Expression.Lambda<Func<TSource, TDest>>(Expression.MemberInit(Expression.New(typeof(TDest)), bindings), parameterExpression);
var key = GetCacheKey<TDest>();
ExpressionCache.Add(key, expression);
return expression;
}
private static MemberAssignment BuildBinding(Expression parameterExpression, MemberInfo destinationProperty, IEnumerable<PropertyInfo> sourceProperties)
{
var sourceProperty = sourceProperties.FirstOrDefault(src => src.Name == destinationProperty.Name);
if (sourceProperty != null)
{
return Expression.Bind(destinationProperty, Expression.Property(parameterExpression, sourceProperty));
}
var propertyNames = SplitCamelCase(destinationProperty.Name);
if (propertyNames.Length == 2)
{
sourceProperty = sourceProperties.FirstOrDefault(src => src.Name == propertyNames[0]);
if (sourceProperty != null)
{
var sourceChildProperty = sourceProperty.PropertyType.GetProperties().FirstOrDefault(src => src.Name == propertyNames[1]);
if (sourceChildProperty != null)
{
return Expression.Bind(destinationProperty, Expression.Property(Expression.Property(parameterExpression, sourceProperty), sourceChildProperty));
}
}
}
return null;
}
private static string GetCacheKey<TDest>()
{
return string.Concat(typeof(TSource).FullName, typeof(TDest).FullName);
}
private static string[] SplitCamelCase(string input)
{
return Regex.Replace(input, "([A-Z])", " $1", RegexOptions.Compiled).Trim().Split(' ');
}
}
公共静态类QueryableExtensions
{
公共静态ProjectionExpression项目(此IQueryable源)
{
返回新的ProjectionExpression(源);
}
公共静态字符串GetSQL(此IQueryable源)
{
返回source.ToString();
}
}
公共类ProjectionExpression
{
私有静态只读字典表达式缓存=新字典();
私有只读可读取源;
公共ProjectionExpression(IQueryable源)
{
_来源=来源;
}
公营机构可(
{
var queryExpression=GetCachedExpression()??BuildExpression();
返回_source.Select(queryExpression);
}
私有静态表达式GetCachedExpression()
{
var key=GetCacheKey();
返回ExpressionCache.ContainsKey(key)?ExpressionCache[key]作为表达式:null;
}
私有静态表达式BuildExpression()
{
var sourceProperties=typeof(TSource).GetProperties();
var destinationProperties=typeof(TDest).GetProperties().Where(dest=>dest.CanWrite);
var parameterExpression=Expression.Parameter(typeof(TSource),“src”);
var bindings=destinationProperties
.Select(destinationProperty=>BuildBinding(parameterExpression、destinationProperty、sourceProperties))
.Where(binding=>binding!=null);
var expression=expression.Lambda(expression.MemberInit(expression.New(typeof(TDest)),bindings),parameterExpression);
var key=GetCacheKey();
ExpressionCache.Add(键,表达式);
返回表达式;
}
私有静态MemberAssignment BuildBinding(表达式参数Expression、MemberInfo destinationProperty、IEnumerable sourceProperties)
{
var sourceProperty=sourceProperties.FirstOrDefault(src=>src.Name==destinationProperty.Name);
if(sourceProperty!=null)
{
返回Expression.Bind(destinationProperty,Expression.Property(parameterExpression,sourceProperty));
}
var propertyNames=SplitCamelCase(destinationProperty.Name);
如果(propertyNames.Length==2)
{
sourceProperty=sourceProperties.FirstOrDefault(src=>src.Name==propertyNames[0]);
if(sourceProperty!=null)
{
var sourceChildProperty=sourceProperty.PropertyType.GetProperties().FirstOrDefault(src=>src.Name==propertyNames[1]);
if(sourceChildProperty!=null)
{
返回Expression.Bind(destinationProperty、Expression.Property(Expression.Property(parameterExpression、sourceProperty)、sourceChildProperty));
}
}
}
返回null;
}
私有静态字符串GetCacheKey()
{
返回字符串.Concat(typeof(TSource).FullName,typeof(TDest).FullName);
}
私有静态字符串[]大小写(字符串输入)
{
返回Regex.Replace(输入“([A-Z])”,“$1”,RegexOptions.Compiled.Trim().Split(”);
}
}
看起来有点像你想要的。