C# 在实体框架存储库中使用选择器

C# 在实体框架存储库中使用选择器,c#,entity-framework,repository,C#,Entity Framework,Repository,当我尝试使用某些返回类型时,我的存储库方法中的Select方法遇到了问题 我遇到问题的存储库方法是: public IEnumerable<T> List(Expression<Func<T, bool>> filter = null, string include = "", int Taked = 0, Expression<Func<T, T>> selector = null)

当我尝试使用某些返回类型时,我的存储库方法中的
Select
方法遇到了问题

我遇到问题的存储库方法是:

public IEnumerable<T> List(Expression<Func<T, bool>> filter = null,
            string include = "", 
            int Taked = 0, Expression<Func<T, T>> selector = null)
{
    IQueryable<T> query = dbSet;
    if (filter != null)
        query = query.Where(filter);

    #region Stringleri İnclude Eder
    foreach (var includeProperty in 
         include.Split(new char[] {','}, 
                       StringSplitOptions.RemoveEmptyEntries))
    {
         query = query.Include(includeProperty);
    }
    #endregion

    if (selector != null)
        query = query.Select(selector);
    if (Taked != 0)
        return query.Take(Taked).ToList();
    return query.ToList();
}

internal DbContext context;
internal DbSet<T> dbSet;
public IEnumerable列表(表达式过滤器=null,
字符串include=“”,
int Taked=0,表达式选择器=null)
{
IQueryable query=dbSet;
if(过滤器!=null)
query=query.Where(过滤器);
#Stringleriİinclude Eder地区
foreach(var包括中的属性)
include.Split(新字符[]{',},
StringSplitOptions.RemoveEmptyEntries)
{
query=query.Include(includeProperty);
}
#端区
if(选择器!=null)
query=query.Select(选择器);
如果(Taked!=0)
返回query.Take(Taked.ToList();
返回query.ToList();
}
内部语境;
内部数据库集;
我想使用上面的方法返回实体类,但我只希望填充某些属性。我尝试过以下方法:

AdminWork workunit = new AdminWork();
IEnumerable<AdminMenu> adminMenus = workunit.Menu.List(x => x.Online == true,
    selector: z => new AdminMenu 
    {
        MenuID = z.MenuID, 
        Name = z.Name, 
        Path = z.Path
    });
AdminWork-workunit=new AdminWork();
IEnumerable AdminMenu=workunit.Menu.List(x=>x.Online==true,
选择器:z=>newadminmenu
{
MenuID=z.MenuID,
Name=z.Name,
路径=z.路径
});
这会引发异常:

不能在LINQ to Entities查询中构造AdminMenu

我还尝试了以下方法,但它需要返回一个
IEnumerable

IEnumerable menus=workunit.Menu.List(x=>x.Online==true,
选择器:z=>z.MenuID);

我的问题是如何在linq to entities中创建实体类的新实例,以便不是每个属性都被填充。

您不能传递创建
AdminMenu
实例的选择器,因为它是在实体框架上下文中映射的类型。所以实体框架希望成为唯一一个创建该类型实例的框架,这样它就可以跟踪更改,如果已经加载,则返回相同的实例,等等。。。有关更多信息,请参阅

因此,如果要返回
AdminMenu
的列表,则不需要传递选择器(因为您开始查询的数据库集已经是该类型的数据库集)。仅当返回类型与dbSet中的类型不同时,才需要传递选择器

您可以使用此方法:(我已将
选择器
设置为非可选参数,因为它将用于定义
TResult
类型。我还假设
T
是类中定义的通用参数,如
公共类存储库
,因此在方法中添加的唯一通用参数是
TResult


答案比我想象的要长,但我希望它能有所帮助

能否显示
dbSet
变量的定义?你能详细介绍一下“返回类型有问题”吗?
IEnumerable<AdminMenu> menus = workunit.Menu.List(x => x.Online == true, 
     selector: z => z.MenuID);
public IEnumerable<TResult> ListProjected<TResult>(Expression<Func<T, TResult>> selector,
                                        Expression<Func<T, bool>> filter = null,
                                        string include = "",
                                        int Taked = 0)
{
    IQueryable<T> query = dbSet;
    if (filter != null)
        query = query.Where(filter);
    #region Stringleri İnclude Eder

    foreach (var includeProperty in include.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
    {
        query = query.Include(includeProperty);
    }

    #endregion

    if (Taked != 0)
        query = query.Take(Taked);

    return query.Select(selector).ToList();
}
public IEnumerable<T> List(Expression<Func<T, bool>> filter = null,
                        string include = "",
                        int Taked = 0)
{
    return ListProjected(x => x, filter, include, Taked);
}
IEnumerable<AdminMenu> menus = workunit.Menu.List(x => x.Online == true);

IEnumerable<int> menuIds = workunit.Menu.ListProjected(x => x.MenuID, 
                                                       x => x.Online == true);
var menuSomeColumnsWithAnonymousObject = workunit.Menu.ListProjected(x => new
{
    MenuID = x.MenuID,
    Path = x.Path,
    Name = x.Name
}, x => x.Id == 1);

var menuSomeColumnsWithDTO = workunit.Menu.ListProjected(x => new AdminMenuDTO
{
    MenuID = x.MenuID,
    Path = x.Path,
    Name = x.Name
}, x => x.Id == 1);