Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.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# 映射IQueryable对象。参数“x”未绑定在指定的LINQ to Entities查询表达式中。_C#_Entity Framework_Linq_Linq To Entities - Fatal编程技术网

C# 映射IQueryable对象。参数“x”未绑定在指定的LINQ to Entities查询表达式中。

C# 映射IQueryable对象。参数“x”未绑定在指定的LINQ to Entities查询表达式中。,c#,entity-framework,linq,linq-to-entities,C#,Entity Framework,Linq,Linq To Entities,我想制作一个类,它可以将IQueryable数据库模型映射到select上的应用程序模型。我使用了此页面中的代码,并对其进行了更改,以添加以下方式使用自定义绑定规则的可能性: var db = new Models.DBContext(); var a = db.User.Map(). Rule<AppModel.AppModel>(dest => dest.Address1, src => src.Address.Select(v => v

我想制作一个类,它可以将IQueryable数据库模型映射到select上的应用程序模型。我使用了此页面中的代码,并对其进行了更改,以添加以下方式使用自定义绑定规则的可能性:

var db = new Models.DBContext();
var a = db.User.Map().
            Rule<AppModel.AppModel>(dest => dest.Address1, src => src.Address.Select(v => v.Address1).FirstOrDefault()).
            Rule<AppModel.AppModel>(dest => dest.Number, src => src.Number.Num).
            To<AppModel.AppModel>().ToList();
但当我使用上述代码时,我出现了错误:

参数“x”未绑定在指定的LINQ to Entities查询表达式中

我知道这是因为我的自定义绑定字典在查询中的parameter对象与主表达式中的parameter对象不同,但我不知道如何在方法规则中更改此参数以重用parameterExpression对象

我的全班同学都喜欢映射:

public static class QueryableExtensions
{
    /// <summary>
    /// Map source object to another type as IQueryable.
    /// </summary>
    /// <typeparam name="TSource"></typeparam>
    /// <param name="source"></param>
    /// <returns></returns>
    public static MapExpression<TSource> Map<TSource>(this IQueryable<TSource> source)
    {
        return new MapExpression<TSource>(source);
    }
}

public class MapExpression<TSource>
{
    static readonly Dictionary<string, Expression> ExpressionCache = new Dictionary<string, Expression>();

    readonly IQueryable<TSource> _source;
    static Dictionary<MemberInfo, Expression> maps = new Dictionary<MemberInfo, Expression>();
    static ParameterExpression parameterExpression = Expression.Parameter(typeof(TSource), "src");

    public MapExpression(IQueryable<TSource> source)
    {
        _source = source;
    }

    /// <summary>
    /// Type to cast
    /// </summary>
    /// <typeparam name="TDest"></typeparam>
    /// <returns></returns>
    public IQueryable<TDest> To<TDest>()
    {
        var queryExpression = GetCachedExpression<TDest>() ?? BuildExpression<TDest>();

        return _source.Select(queryExpression);
    }

    public MapExpression<TSource> Rule<TDest>(Expression<Func<TDest, object>> dest, Expression<Func<TSource, object>> src)
    {
        var d = (dest.Body as MemberExpression).Member;
        maps.Add(d, src);

        return this;
    }

    static Expression<Func<TSource, TDest>> GetCachedExpression<TDest>()
    {
        var key = GetCacheKey<TDest>();

        return ExpressionCache.ContainsKey(key) ? ExpressionCache[key] as Expression<Func<TSource, TDest>> : null;
    }

    static Expression<Func<TSource, TDest>> BuildExpression<TDest>()
    {
        var sourceProperties = typeof(TSource).GetProperties();
        var destinationProperties = typeof(TDest).GetProperties().Where(dest => dest.CanWrite);

        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;
    }

    static MemberAssignment BuildBinding(Expression parameterExpression, MemberInfo destinationProperty, IEnumerable<PropertyInfo> sourceProperties)
    {
        var sourceProperty = sourceProperties.FirstOrDefault(src => src.Name == destinationProperty.Name);

        if (sourceProperty != null && ((PropertyInfo)destinationProperty).PropertyType == sourceProperty.PropertyType)
            return Expression.Bind(destinationProperty, Expression.Property(parameterExpression, sourceProperty));

        if (maps.ContainsKey(destinationProperty))
        {
            var x = ((LambdaExpression)maps[destinationProperty]).Body;
            return Expression.Bind(destinationProperty, x);
        }

        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;
    }

    static string GetCacheKey<TDest>() =>
        string.Concat(typeof(TSource).FullName, typeof(TDest).FullName);

    static string[] SplitCamelCase(string input) =>
        Regex.Replace(input, "([A-Z])", " $1", RegexOptions.Compiled).Trim().Split(' ');


}

您是否尝试过使用较新版本的automapper。是否处理自定义项目AWW,我不知道,automapper可以使用IQueryable,谢谢!