Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#-选择实体和变量LINQ/query_C#_Entity Framework 4.1 - Fatal编程技术网

C#-选择实体和变量LINQ/query

C#-选择实体和变量LINQ/query,c#,entity-framework-4.1,C#,Entity Framework 4.1,我正在使用C#构建一个文件下载服务——该过程的一部分是验证从一个或多个数据库下载的内容,并提供下载的详细信息 验证过程可以调用四个数据库——这实际上取决于下载的服务。数据库是MSSQL或MySQL,可以使用存储过程(复杂类型)或具有多个联接的LINQ查询。所有结果将包含相同的列信息 我已经在Entity框架中定义了数据库,我对单个实例中的代码很满意——如果我查询不同的数据库,我不想再次编写执行相同任务的代码 我已经搜索了几个小时,试图找到一个解决方案,使我能够根据条件指定要使用的实体和查询,并使

我正在使用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(”);
}
}

看起来有点像你想要的。