Использование Contains () для включенного объекта - PullRequest
0 голосов
/ 04 февраля 2019

У меня есть следующий код:

    public PaginatedList<PdModel> PdModel { get; set; }
    public async Task OnGetAsync(int id, int? pageIndex, string searchString)
    {
        IQueryable<PdModel> PdModelsQuer = _context.PdModel.Where(x => x.Id == id)
                                .Include(x => x.PdTables)
                                .Include(x => x.pdFolderTree)
                                .Include(x => x.PdReferences.Where(y=>y.ReferenceName.Contains(searchString)))
                                .Include(x => x.pdViews)
                                .Include(x => x.pdDomains)
                                .Include(x => x.PdModelSources)
                                .Include(x => x.pdModelExtendeds)
                                .Include(x => x.pdRules);






        PdModel = await PaginatedList<PdModel>.CreateAsync(PdModelsQuer, 1, 10);
    }

При выполнении кода я получаю эту ошибку:

InvalidOperationException: выражение свойства 'x => {из PdReference y в x.PdReferencesгде [y] .ReferenceName.Contains (__ searchString_1) select [y]} 'недопустимо.Выражение должно представлять доступ к свойству: 't => t.MyProperty'.Для получения дополнительной информации о включении связанных данных см. http://go.microsoft.com/fwlink/?LinkID=746393.

Я предполагаю, что мне нужно использовать Contains () для включенного свойства другим способом.Я много чего перепробовал, но никакой разумный код не работает.

Кто-нибудь может мне помочь в этом?

Заранее большое спасибо

Модели моего домена:

public class PdModel
    {
        [Key]
        public int Id { get; set; }
        public string ModelCode { get; set; }
        public string ModelName { get; set; }
        public string ModelComment { get; set; }
        public string ModelDescription { get; set; }
        public string ModelAnnotation { get; set; }
        public string ModelDatabase { get; set; }
        public DateTime? ModelCreationDate { get; set; }
        public string ModelCreationUser { get; set; }
        public DateTime? ModelModificationDate { get; set; }
        public string ModelModificationUser { get; set; }
        public string ModelGarantExtendedFlag { get; set; }
        public string ModelColumnExtendedFlag { get; set; }
        public string ModelTableExtendedFlag { get; set; }
        public DateTime PdInsertedDate { get; set; }

        public ICollection<PdRule> pdRules { get; set; }
        public ICollection<PdModelExtended> pdModelExtendeds {get;set;}
        public ICollection<PdTable> PdTables { get; set; }
        public ICollection<PdReference> PdReferences { get; set; }
        public ICollection<PdModelSource> PdModelSources { get; set; }
        public ICollection<PdDomain> pdDomains { get; set; }
        public ICollection<PdView> pdViews { get; set; }
        [ForeignKey("Id")]
        public virtual PdFolderTree pdFolderTree { get; set; }


    }

    public class PdReference
    {
        public int Id { get; set; }
        public int ModelId { get; set; }
        public string ModelCode { get; set; }
        public string ReferenceCode { get; set; }
        public string ReferenceName { get; set; }
        public string ReferenceComment { get; set; }
        public string ReferenceDescription { get; set; }
        public string ReferenceAnnotation { get; set; }
        public string ReferenceStereotype { get; set; }
        public int ParentModelId { get; set; }
        public string ParentModelCode { get; set; }
        public string ParentTableCode { get; set; }
        public int ParentTableId { get; set; }
        public int ChildTableId { get; set; }
        public string ChildTableCode { get; set; }
        public string Cardinality { get; set; }
        public DateTime PdInsertedDate { get; set; }


        [ForeignKey("ModelId")]
        public PdModel PdModels { get; set; }

        public ICollection<PdJoin> pdJoins { get; set; }
        [ForeignKey("ChildTableId")]
        public virtual PdTable pdChildTable { get; set; }

1 Ответ

0 голосов
/ 04 февраля 2019

Вы не можете фильтровать загруженные отношения.Ошибка, которую вы получаете, связана с тем, что Include необходимо передать правильное выражение свойства, которое не является предложением Where.

Если вы хотите загрузить только подмножество этого конкретного отношения, выВам нужно будет явно загрузить его.Например:

IQueryable<PdModel> PdModelsQuer = _context.PdModel.Where(x => x.Id == id)
                            .Include(x => x.PdTables)
                            .Include(x => x.pdFolderTree)
                            // remove this .Include(x => x.PdReferences.Where(y=>y.ReferenceName.Contains(searchString)))
                            .Include(x => x.pdViews)
                            .Include(x => x.pdDomains)
                            .Include(x => x.PdModelSources)
                            .Include(x => x.pdModelExtendeds)
                            .Include(x => x.pdRules);

foreach (var pdModel in PdModelsQuer)
{
    var pdReferences = await _context.Entry(pdModel).Collection(x => x.PdReferences).Query()
        .Where(x = x.ReferenceName.Contains(searchString)).ToListAsync();
}

Если это не очевидно, это означает выдачу N + 1 запросов, где N - количество ваших PdModels.Другими словами, отфильтрованная коллекция должна выбираться для каждого экземпляра индивидуально.

Однако, основываясь на запросах по id, кажется, что у вас должен быть только один соответствующий PdModel.Таким образом, вы действительно не должны использовать Where здесь.Вместо.Просто добавьте все ваши включения и затем используйте SingleOrDefaultAsync:

var pdModel = await _context.PdModel
    .Include(x => x.PdTables)
    .Include(x => x.pdFolderTree)
    .Include(x => x.pdViews)
    .Include(x => x.pdDomains)
    .Include(x => x.PdModelSources)
    .Include(x => x.pdModelExtendeds)
    .Include(x => x.pdRules)
    .SingleOrDefaultAsync(x => x.Id == id);

Затем вы можете получить PdReferences только для этого одного экземпляра:

var pdReferences = await _context.Entry(pdModel).Collection(x => x.PdReferences).Query()
    .Where(x = x.ReferenceName.Contains(searchString)).ToListAsync();

Важно отметить, что этохранится в другой переменной.Установка отфильтрованной коллекции непосредственно в свойстве PdReferences может вызвать побочные эффекты, особенно если вы в конечном итоге попытаетесь сохранить эту сущность позже, а именно, удалить что-либо, отсутствующее в отфильтрованном списке, из базы данных.В такой ситуации лучше всего использовать модель представления и соответствующим образом отображать данные.

...