2016-04-11 3 views
0

Оригинальный вопрос: here. Где я пытался найти способ ограничить количество столбцов, возвращенных из базы данных, с помощью шаблона хранилища и единицы работы. Мой вопрос нашел ответ, но я не решил его и решил опубликовать новую проблему, которая возникла с использованием этой техники, поскольку проблема, с которой я сейчас сталкиваюсь, является совершенно новой темой.Dynamic Linq Select with Lambda

В хранилище, у меня есть метод 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. 

UPDATE 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; } 
} 
} 
+0

Тип возврата для операции выбора не собирается быть 'Authors.Author' ... Вам проецируют новый анонимный тип, когда вы выбираете. В зависимости от того, что вы пытаетесь сделать, вы можете просто объявить авторов как 'var' –

+0

Рассмотрите возможность использования динамического LINQ. Или посмотрите на [this] (http://stackoverflow.com/a/723018/861716), который, я думаю, дублирует вопрос. –

+0

Спасибо, Герт, но есть слишком много, чтобы переварить для меня. Мне бы лучше избавиться от шаблона репозитория, если то, что кажется простой задачей, - это то, что нужно написать много кода. –

ответ

1

Вы просите хранилища для возврата для каждой записи в запросе привести новый анонимный объект:

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

Но в то же время переменное вы объявили это типа IEnumerable<Models.Authors.Author>

Для того, чтобы сделать его работу вам нужно, чтобы вернуть объекты 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 }); 

UPDATE

Поскольку вы не можете использовать уже отображенные контекстные объекты в вас запросов, из-за «сущностей или сложного типа„...“не может быть построенной ", лучшее решение, которое я вижу, - это иметь отдельный класс с несколькими свойствами, которые необходимы для вашей страницы.Как:

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 }); 
+0

Спасибо, Павел, но, пожалуйста, см. Мой обновленный ответ, поскольку я пробовал это еще раньше, и они дают ошибки, упомянутые в моем обновлении. ваше второе предложение также дает те же ошибки, о которых я упоминаю в своем вопросе. –

+0

Не могли бы вы поделиться классом Author? Похоже, что это не просто модель домена со свойствами –

+0

Я только что обновил вопрос .. Спасибо за ваше время pavel –