Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.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# 如何从C中的IQueryable中选择特定列_C#_Entity Framework_Entity_Iqueryable - Fatal编程技术网

C# 如何从C中的IQueryable中选择特定列

C# 如何从C中的IQueryable中选择特定列,c#,entity-framework,entity,iqueryable,C#,Entity Framework,Entity,Iqueryable,我需要从IQueryble中动态选择一些列 例如: IQueryable<Car> query = (from a in _dbContext.Table1 select new Car { Prop1 = a.Prop1, Prop2 = a.Prop2,

我需要从IQueryble中动态选择一些列

例如:

IQueryable<Car> query = (from a in _dbContext.Table1
                     select new Car
                     {
                         Prop1 = a.Prop1,
                         Prop2 = a.Prop2,
                         Prop3 = a.Prop3
                     });
在数据库中的正确搜索应为:

SELECT 
[Limit1].[C1] AS [C1], 
[Limit1].[Prop1] AS [Prop1]
FROM ( ...

在数据库中搜索之前,我需要操作IQueryable。

您遇到的问题是将Func传递给Select。这本质上意味着该方法在内存中执行,而不是在数据库中执行

实体框架无法从已编译函数生成SQL代码

当你写这篇文章时:

var users = Users.Select(u => new User { a = 1 });
var users = Users.Select(u => new NotAnEntityUser { a = 1 });
您正在向它传递一个表达式,实体框架可以将该表达式转换为SQL

因此,您需要更改的是函数的结尾。与此相反:

var lambda = Expression.Lambda<Func<T, T>>(xInit, xParameter);
return lambda.Compile()
我们需要这样写:

var users = Users.Select(u => new User { a = 1 });
var users = Users.Select(u => new NotAnEntityUser { a = 1 });
然后,我们需要更改我们的方法以返回一个notationEntityUser,而不是一个User

这样你就可以写:

var lam = new Test().CreateNewStatement<User, NotAnEntityUser>("Id");
var c = new MyContext().Users.Select(lam).AsEnumerable().Select(u => (User)u).ToList();
除了编写隐式cast操作符,还可以使用automapper等工具

使用automapper,您将得到如下结果:

var c = AutoMapper.Map<List<User>>(new MyContext().Users.Select(lam).ToList());

奇妙的解释,当然他妈的正确。然而,解决方案是如此复杂,以至于我放弃了lambda表达式,并对Sql执行了一个简单的Linq!
var users = Users.Select(u => new User { a = 1 });
var users = Users.Select(u => new NotAnEntityUser { a = 1 });
public class Test
{
    public Expression<Func<TEntityType, TModelType>> CreateNewStatement<TEntityType, TModelType>(string fields)
    {
        var xParameter = Expression.Parameter(typeof (TEntityType), "o");
        var xNew = Expression.New(typeof (TModelType));

        var bindings = fields.Split(',').Select(o => o.Trim())
            .Select(paramName =>
            {
                var xOriginal = Expression.Property(xParameter, typeof(TEntityType).GetProperty(paramName));
                return Expression.Bind(typeof(TModelType).GetProperty(paramName), xOriginal);
            }
            );
        var xInit = Expression.MemberInit(xNew, bindings);

        var lambda = Expression.Lambda<Func<TEntityType, TModelType>>(xInit, xParameter);
        return lambda;
    }
}
public class User
{
    public virtual string Id { get; set; }
    public virtual string UserName { get; set; }
    public virtual string Salt { get; set; }

    public static implicit operator User(NotAnEntityUser o)
    {
        return new User { Id = o.Id, UserName = o.UserName, Salt = o.Salt };
    }
}
public class NotAnEntityUser
{
    public virtual string Id { get; set; }
    public virtual string UserName { get; set; }
    public virtual string Salt { get; set; }
}
var lam = new Test().CreateNewStatement<User, NotAnEntityUser>("Id");
var c = new MyContext().Users.Select(lam).AsEnumerable().Select(u => (User)u).ToList();
SELECT 
    1 AS [C1], 
    [Extent1].[Id] AS [Id]
    FROM [dbo].[User] AS [Extent1]
var c = AutoMapper.Map<List<User>>(new MyContext().Users.Select(lam).ToList());