Могу ли я сделать подзапрос в SELECT LINQ to Entities для заполнения списка в модели?

Возможно ли иметь подзапрос в части .Select запроса LINQ to Entities, чтобы заполнить List<string> внутри моей модели представления? Я нашел Использовать Linq To Entities подзапрос в предложении Select для получения значения поля, но когда я пытаюсь это сделать, я получаю сообщение об ошибке:

NotImplementedException: Microsoft.Data.Entity.Query.ResultOperators.Internal.QueryAnnotationResultOperator

Возможно ли это сделать с Entity Framework 7 и ASP.Net 5 MVC 6?

var model = _DbContext.ReleaseVersions
                        .OrderByDescending(rv => rv.DateReleased)
                        .Select(rv => new ReleaseNotesVM()
                        {
                            ID = rv.ID,
                            CurrentVersion = string.Concat(rv.Major, '.', rv.Minor, '.', rv.Patch),
                            ReleaseNotes = _DbContext.ReleaseNotes
                                                    .Where(rn => rn.ReleaseVersionID == rv.ID)
                                                    .Include(rn => rn.ReleaseVersion)
                                                    .Select(rn => rn.Note)
                                                    .ToList()
                        }).FirstOrDefault();

ViewModel заполняется:

public class ReleaseNotesVM
{
    public byte ID { get; set; }
    public string CurrentVersion { get; set; }
    public DateTime CurrentVersionReleaseDate { get; set; }
    public IEnumerable<SelectListItem> VersionList { get; set; }
    public byte SelectedVersionID { get; set; }
    public ICollection<string> ReleaseNotes { get; set; }
}

Модель данных:

public class ReleaseVersion
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public byte ID { get; set; }

    public DateTime DateReleased { get; set; }
    public byte Major { get; set; }
    public byte Minor { get; set; }
    public byte Patch { get; set; }

    public virtual ICollection<ReleaseNote> ReleaseNotes { get; set; }
}
public class ReleaseNote
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }

    public string Note { get; set; }
    public byte ReleaseVersionID { get; set; }

    [ForeignKey("ReleaseVersionID")]
    public ReleaseVersion ReleaseVersion { get; set; }
}

person Matthew Verstraete    schedule 18.01.2016    source источник
comment
Почему бы вам просто не использовать rv.ReleaseNotes вместо того, чтобы выбирать его снова и снова?   -  person TKharaishvili    schedule 19.01.2016
comment
@GwynBleidd, потому что именно так это показано в связанном сообщении SO.   -  person Matthew Verstraete    schedule 19.01.2016


Ответы (1)


Если я правильно предполагаю, у вас должна быть связь «один ко многим» между ReleaseVersions и ReleaseNotes, что означает, что в классе ReleaseVersion должно быть свойство навигации, ссылающееся на коллекцию ReleaseNotes, что позволит вам переписать свой код следующим образом:

var model = _DbContext.ReleaseVersions
                    .Include(rv => rv.ReleaseNotes)
                    .OrderByDescending(rv => rv.DateReleased)
                    .Select(rv => new ReleaseNotesVM
                    {
                        ID = rv.ID,
                        CurrentVersion = string.Concat(rv.Major, '.', rv.Minor, '.', rv.Patch),
                        ReleaseNotes = rv.ReleaseNotes.Select(rn => rn.Note).ToList()
                    }).FirstOrDefault();

Обновить

Используйте List<string> ReleaseNotes вместо ICollection<string> в ReleaseNotesVM.

person TKharaishvili    schedule 18.01.2016
comment
Я добавил public virtual ICollection<ReleaseNote> ReleaseNotes { get; set; } к ReleaseVersion, но теперь, когда я делаю ReleasEnotes = rv.ReleaseNotes, я получаю сообщение об ошибке Cannot implicitly convert IColleciton<ReleaseNote> to Icollection<string>. - person Matthew Verstraete; 19.01.2016
comment
@MatthewVerstraete Я обновил ответ. Обратите внимание, что я также обновил сам оператор select, чтобы он соответствовал вашим требованиям. - person TKharaishvili; 19.01.2016