使用Lambda选择动态Linq

时间:2016-04-11 20:02:35

标签: c# entity-framework linq

我的原始问题是here。我试图找到一种方法来限制使用Repository Pattern和Unit of Work从数据库返回的列数。我的问题找到答案,但我没有解决它,并决定发布使用该技术产生的新问题,因为我现在要解决的问题是一个全新的主题。

在存储库中,我有一个Get方法,它采用以下参数:

public virtual IEnumerable<TEntity> Get(
        Expression<Func<TEntity, bool>> filter = null,
        Func<TEntity, TEntity> selector = null,
        Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
        string includeProperties = "")

以下在我的控制器内部运行良好:

IEnumerable<Models.Authors.Author> authors = unitOfWork.AuthorRepository.Get(filter: x => x.TenantID == 1);

但是,我无法让“选择”部分工作:

IEnumerable<Models.Authors.Author> authors = unitOfWork.AuthorRepository.Get(filter: x => x.TenantID == 1, selector: a=> new { FirstName = a.FirstName } );

同样地,这个:

var authors = unitOfWork.AuthorRepository.Get(filter: x => x.TenantID == 1, selector: a=> new { FirstName = a.FirstName } );

给出以下两个错误:

Cannot implicitly convert type '<anonymous type: string FirstName>' to 'Models.Authors.Author'

Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type

我对此完全陌生。所以我非常感谢你的帮助......

已更新

这样:

IEnumerable<Models.Authors.Author> authors = unitOfWork.AuthorRepository.Get(filter: x => x.TenantID == 1, selector: a=> new Models.Authors.Author() { FirstName = a.FirstName } );

给出了这个:

The entity or complex type 'DAL.Author' cannot be constructed in a LINQ to Entities query.

更新2:作者类 //名称空间是

namespace Models.Authors
{
public class Author
{
    [Key]
    public int AuthorID { get; set; }
    public int CategoryID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string PhotoPath { get; set; }
    public byte[] PhotoBinary { get; set; }
    public string PhotoPathOriginal { get; set; }
    public string UserName { get; set; }
    public string Password { get; set; }
    public Guid? PassGuid { get; set; }
    public string Email { get; set; }
    public string Twitter { get; set; }
    public string Facebook { get; set; }
    public DateTime? DateCreated { get; set; }
    public DateTime? DateLastlogin { get; set; }
    public int AuthorStatus { get; set; } // 0:inactive, 1:active, 2:suspended, 3:hidden etc.
    public string AboutAuthor { get; set; }
    public bool? RequirePublishApproval { get; set; }
    public string ColumnName { get; set; }
    public string ColumnImage { get; set; }
    public bool? ChangePassAtFirstLogin { get; set; }
    public int TenantID { get; set; }

    public virtual AuthorCategory AuthorCategory { get; set; }
    public virtual IQueryable<Post.Post> Posts { get; set; }
}
}

1 个答案:

答案 0 :(得分:1)

您要求存储库为查询结果中的每个记录返回一个新的匿名对象:

selector: a => new { FirstName = a.FirstName }

但与此同时,您声明的变量属于IEnumerable<Models.Authors.Author>

类型

为了使其工作,您需要在select中返回Models.Authors.Author对象:

IEnumerable<Models.Authors.Author> authors = unitOfWork.AuthorRepository.Get(filter: x => x.TenantID == 1, selector: a=> new Models.Authors.Author() { FirstName = a.FirstName } );

或者,您可以使用匿名对象,但需要将变量声明为var

var authors = unitOfWork.AuthorRepository.Get(filter: x => x.TenantID == 1, selector: a=> new { FirstName = a.FirstName } );

更新

由于您不能在查询中使用已映射的上下文实体,因为&#34;实体或复杂类型&#39; ...&#39;不能建造&#34;错误,我看到的最佳解决方案是创建一个单独的类,其中包含页面所需的几个属性。像:

public class AuthorDetails {
   public string FirstName {get; set;}
}

然后在查询和视图中使用此类:

var authors = unitOfWork.AuthorRepository.Get(filter: x => x.TenantID == 1, selector: a=> new AuthorDetails { FirstName = a.FirstName } );