#c# #entity-framework #linq #asp.net-web-api
Вопрос:
У меня проблема. У меня есть две таблицы по отношению «один» ко «многим». У меня есть список, который является подмножеством элементов в таблице на стороне «много». Я хочу получить элементы из таблицы на стороне «один», которые имеют отношение ко всем элементам на стороне «много». Я попробовал что-то вроде
public async Task<GetQuestionsDTO> GetQuestions(int skip, SortOptionEnum sortOption,
List<int> tags)
{
IQueryable<Question> QuestionQuery = _context.Questions.AsQueryable();
int count;
if (tags.Count != 0)
{
QuestionQuery = QuestionQuery
.Where(question => _context.QuestionTags
.Where(tag=>tag.IdQuestion == question.IdQuestion)
.Select(tag=> tag.IdTag)
.ToList()
.Intersect(tags)
.Equals(tags)
);
}
count = await QuestionQuery.CountAsync();
switch (sortOption)
{
case SortOptionEnum.Views:
QuestionQuery = QuestionQuery.OrderBy(question => question.Views);
break;
case SortOptionEnum.Answers:
QuestionQuery = QuestionQuery.OrderBy(question => question.Answers.Count);
break;
case SortOptionEnum.Date:
QuestionQuery = QuestionQuery.OrderByDescending(question => question.PublishDate);
break;
}
QuestionQuery = QuestionQuery.Skip(_skip).Take(_takeAmount);
return new GetQuestionsDTO()
{
StandardQuestions = await QuestionQuery.Select(question => new QuestionGetQuestionsDTO()
{
IdQuestion = question.IdQuestion,
AnswersCount = question.Answers.Count,
Avatar = question.IdUserNavigation.Avatar,
Tags = question.QuestionTags.Select(qt => qt.IdTagNavigation.Name).ToList(),
Description = question.Description,
Header = question.Header,
IdUser = question.IdUser,
IsFinished = question.IsFinished,
IsModified = question.IsModified,
Nickname = question.IdUserNavigation.Nickname,
Views = question.Views,
PublishDate = question.PublishDate
}).ToListAsync(),
QuestionsCount = count
};
}
но я понимаю
System.ArgumentException: Expression of type 'System.Collections.Generic.List ``1[System.Int32]' cannot be used for parameter of type 'System.Linq.IQueryable``1[System.Int32]' of method 'System.Linq.IQueryable``1[System.Int32] Intersect[Int32](System.Linq.IQueryable``1[System.Int32], System.Collections.Generic.IEnumerable``1[System.Int32])' (Parameter 'arg0')
Есть ли какой-либо способ сделать это с помощью EntityFramework или мне следует использовать хранимую процедуру в базе данных?
Комментарии:
1. Ваш запрос выглядит более сложным, чем я себе представляю. Чтобы подтвердить….. у вас есть таблица вопросов, связанная с таблицей тегов вопросов в соотношении один ко многим. Массив тегов вашего метода представляет собой список идентификаторов тегов, которые соответствуют идентификатору tagid в таблице тегов вопросов?
2. Да, это так
Ответ №1:
Я думаю, что это сработает. Вопросы, в которых tagid тегов вопросов находится в массиве tagids.
IQueryable<Question> questions = context.Questions;
foreach(int tagid in tagsid){
questions = questions.Where(w=> w.QuestionTags.Select(s=> s.TagId).Contains(tagid));
}
Построение запроса таким образом означает, что в вопросе должны быть по крайней мере все теги, указанные в вашем параметре.
Поэтому важно, чтобы ваш параметр имел идентификатор 1,2,3, запрос выполнялся. Вопрос должен иметь Метку вопроса, содержащую 1, затем вопрос должен содержать метку вопроса, содержащую и т. Д
Комментарии:
1. Я на мобильном телефоне, поэтому не могу подтвердить синтаксис. Кроме того, это предполагает, что у вас есть свойства навигации между объектами.
2. Это не работает :/. Не является ли second, где возвращается набор тегов вопросов? Да, у меня есть собственные средства навигации между объектами.
3. Когда вы говорите, что это не работает, что это делает? Во втором случае, когда данные не возвращаются, у вас все еще возникают вопросы. Вы просто получаете вопросы, в которых связанные теги вопросов имеют идентификаторы в массиве.
4.
I get an error: CS0029 Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<Models.QuestionTag>' to 'bool'
и программа не будет компилироваться5. Я обновлю: Измените второе место на любое. Должно сработать