[英]EF 6, LINQ how to create where inside include with conditional parameter
I have 4 tables 我有4张桌子
tblTraining
-----------
ID
Name
tblQuestion
----------
ID
Name
Active (true / false)
(FK) TrainingID
tblAnswer
----------
ID
Name
Active (true / false)
(FK) QuestionID
tblEmployeeTraining
-------------------------
ID
(FK) EmployeeID
(FK) TrainingID
Each Training has many Questions, and each Question has many Answers. 每个培训都有很多问题,每个问题都有很多答案。 I also have tblEmployeeTraining to store every employee that do the related training.
我也有tblEmployeeTraining来存储每位进行相关培训的员工。
I wanna to get the training object by training ID, but I have conditional parameter to include the Question or EmployeeTraining. 我想通过培训ID获取培训对象,但是我有条件参数包括Question或EmployeeTraining。
So here I call my query: 所以在这里我打电话给我的查询:
GetTraining(dbContext, ID: 1, includeEmployeeTrainings: true, includeQuestions: false);
here my GetTraining Function: 这是我的GetTraining函数:
public static TrainingCourse GetTraining(dbContext, int ID = 0,
bool includeEmployeeTrainings = false, bool includeQuestions = false)
{
try
{
IQueryable<tblTraining> training = (
from tc in dbContext.tblTraining
select tc);
//where
if (ID != 0) training = training.Where(tc => tc.ID == ID);
//include
var includeQuestionQuery = includeQuestions ? training.Select(tc => new
{
Questions = tc.tblQuestions.Where(qq => qq.IsActive == true),
Answers = tc.tblQuestions.Select(qq => qq.tblAnswers.Where(qa => qa.IsActive == true)),
}) : null;
var includeEmployeeTrainingsQuery = includeEmployeeTrainings ? training.Select(tc => new
{
EmployeeTrainings = tc.tblEmployeeTrainings.AsEnumerable()
}) : null;
training = training.Select(tc => new
{
tc,
includeQuestionQuery,
includeEmployeeTrainingsQuery,
}).AsEnumerable().Select(tc => tc.tc).AsQueryable();
return training.FirstOrDefault();
}
catch
{
throw;
}
}
the above code will work perfectly if I call like this 如果我这样调用,上面的代码将完美地工作
GetTraining(dbContext, 1, includeEmployeeTrainings: true, includeQuestions: true);
but get an error if I call like this 但是如果我这样打来就会出错
GetTraining(dbContext, 1, includeEmployeeTrainings: false, includeQuestions: true);
Unable to create a null constant value of type 'System.Linq.IQueryable
1[[<>f__AnonymousType2
1[[System.Collections.Generic.IEnumerable`1[[.....]]'.无法创建类型为'System.Linq.IQueryable
1[[<>f__AnonymousType2
1 [[System.Collections.Generic.IEnumerable`1 [[.....]]]”的空常量。 Only entity types, enumeration types or primitive types are supported in this context在此上下文中仅支持实体类型,枚举类型或原始类型
I know the error is because in GetTraining Function, the includeEmployeeTrainingsQuery is null. 我知道错误是因为在GetTraining函数中,includeEmployeeTrainingsQuery为null。 But how do I do solve this problem ?
但是我该如何解决这个问题呢?
Your problem is, that the compiler cannot work out the type of null in your anonymous type variable training
. 您的问题是,编译器无法在您的匿名类型变量
training
出null的类型。
One solution would be to create a strongly typed result using ViewModels. 一种解决方案是使用ViewModels创建强类型结果。 Those can be null using something like
(Viewmodelclass)null
. 可以使用
(Viewmodelclass)null
类的参数将(Viewmodelclass)null
。 Or you can simply avoid assigning null using classic if statements, instead of ternary operators: 或者,您可以避免使用经典if语句而不是三元运算符来分配null:
public class QuestionsQueryVm {
public foo bar {get; set; }
}
public class EmplyeeTrainingVm {
public foo bar {get; set; }
}
public class TrainingVm {
public QuestionsVm Questions { get; set;}
public EmployeeTrainingsVm EmployeeTraining { get; set; }
public Training Training
}
So now you can start from the top: 现在,您可以从顶部开始:
var training = dbContext.tblTraining.Where(tc => tc.ID == ID)
var trainingVm = new TrainingVm {
Training = training.FirstOrDefault(), // should be only one
};
if(includeQuestions)
{
var questions = training.Select(tc => new QuestionsQueryVm
{
Questions = tc.tblQuestions.Where(qq => qq.IsActive == true),
Answers = tc.tblQuestions.Select(qq => qq.tblAnswers.Where(qa => qa.IsActive == true)),
});
trainingVm.Questions = questions;
}
if(includeEmployeeTrainings)
{
employeeTraining = training.Select(tc => newEmplyoeeTraingVm
{
EmployeeTrainings = tc.tblEmployeeTrainings.AsEnumerable()
});
trainingVm.EmployeeTraining = employeeTraining;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.