[英]Entity Framework, LINQ Query
How to loop through the Items below and update the Field which have empty values with the value (!) Error:如何遍历下面的项目并使用值 (!) 错误更新具有空值的字段:
Cannot implicitly convert type System.threading.task to System.Collections.Generic.IEnumerable<Respositories.AssignmentMasterData>
无法将 System.threading.task 类型隐式转换为 System.Collections.Generic.IEnumerable<Respositories.AssignmentMasterData>
using (SUPEntities db = new SUPEntities())
{
IEnumerable<AssignementMasterData> masterDatas = null;
masterDatas = db.AssignementMasterDatas
.Where(m => DbFunctions.TruncateTime(m.CreatedDateTime) >= DbFunctions.TruncateTime(criteria.FilterStartDate)
&& DbFunctions.TruncateTime(m.CreatedDateTime) <= DbFunctions.TruncateTime(criteria.FilterEndDate)
&& (m.AssignmentNoteNumber == criteria.AssigmentNumber || criteria.AssignmentNumber == null)
&& (m.BaseCourseId == criteria.courseId || criteria.CourseId == 0)
&& (m.AccountNumber == criteria.AccountNumber || criteria.AccountNumber == null)
&& (m.ReferenceNumber == criteria.ReferenceNumber || criteria.ReferenceNumber == null)
&& (m.FacultyCode == criteria.FAcultyCode || criteria.FacultyCode == null)
&& (m.Processed == criteria.Processed)
&& (m.ClassNumber == criteria.ClassNumber || criteria.ClassNumber == null))
.ForEachAsync(t => t.AssignmentNoteIdentifiedClasses.Select(e => String.IsNullOrEmpty(e.Category)? "(!)": e.Category));
}
Firstly, about the error message:首先,关于错误信息:
You are trying to assign the wrong type to your masterDatas
variable.您正在尝试为
masterDatas
变量分配错误的类型。 You declare it as a IEnumerable<Respositories.AssignmentMasterData>
, but the ForEachAsync
at the last line will return a Task
, hence the error message.您将其声明为
IEnumerable<Respositories.AssignmentMasterData>
,但最后一行的ForEachAsync
将返回Task
,因此会返回错误消息。
See the ForEachAsync
signature:请参阅
ForEachAsync
签名:
public static System.Threading.Tasks.Task ForEachAsync (this System.Linq.IQueryable source, Action action);
公共静态 System.Threading.Tasks.Task ForEachAsync(这个 System.Linq.IQueryable 源,Action 动作);
Secondly.其次。 You want to return an
IEnumerable<Respositories.AssignmentMasterData>
你想返回一个
IEnumerable<Respositories.AssignmentMasterData>
For that you don't need the call to ForEachAsync.为此,您不需要调用 ForEachAsync。
You will need to some point transform your IQueryable
into an IEnumerable
.您需要将
IQueryable
转换为IEnumerable
。 A call to AsEnumerable()
does that.对
AsEnumerable()
调用就是这样做的。 Then you need to replace some values.然后你需要替换一些值。 So you need to project your collection using a
Select
.因此,您需要使用
Select
来投影您的收藏。
using (SUPEntities db = new SUPEntities())
{
var masterDatas = db.AssignementMasterDatas
.Where(m => DbFunctions.TruncateTime(m.CreatedDateTime) >= DbFunctions.TruncateTime(criteria.FilterStartDate)
&& DbFunctions.TruncateTime(m.CreatedDateTime) <= DbFunctions.TruncateTime(criteria.FilterEndDate)
&& (m.AssignmentNoteNumber == criteria.AssigmentNumber || criteria.AssignmentNumber == null)
&& (m.BaseCourseId == criteria.courseId || criteria.CourseId == 0)
&& (m.AccountNumber == criteria.AccountNumber || criteria.AccountNumber == null)
&& (m.ReferenceNumber == criteria.ReferenceNumber || criteria.ReferenceNumber == null)
&& (m.FacultyCode == criteria.FAcultyCode || criteria.FacultyCode == null)
&& (m.Processed == criteria.Processed)
&& (m.ClassNumber == criteria.ClassNumber || criteria.ClassNumber == null))
.AsEnumerable()
.Select(a =>
{
a.AssignmentNoteIdentifiedClasses = a.AssignmentNoteIdentifiedClasses
.Select(e =>
{
e.Category = string.IsNullOrWhiteSpace(e.Category) ? "(!)" : e.Category;
return e;
})
.ToList(); // Depending on the type of AssignmentNoteIdentifiedClasses, ToList() might be replaced.
return a;
});
return masterDatas
}
.Include( m => m.AssignmentNoteIdentifiedClasses )
to bring-in related data in a single query, this is much faster than loading each set of related AssignmentNoteIdentifiedClasses
in your for-each-row loop..Include( m => m.AssignmentNoteIdentifiedClasses )
在单个查询中引入相关数据,这比在 for-each-row 循环中加载每组相关的AssignmentNoteIdentifiedClasses
快得多。
TruncateTime
.TruncateTime
。
criteria.FilterStartDate
down to the start-of-day in application code and compare it normally with m => m.CreatedDateTime >= filterStart
.criteria.FilterStartDate
向下舍入到应用程序代码中的开始日期,然后将其与m => m.CreatedDateTime >= filterStart
进行正常比较。FilterEndDate
should be rounded-up and then compared like so: m => m.CreatedDateTime < filterEnd
FilterEndDate
应该四舍五入,然后像这样比较: m => m.CreatedDateTime < filterEnd
&&
in your Where
.&&
在您的Where
。 Use additional separate .Where()
clauses instead..Where()
子句。 They'll be evaluated with AND
AND
进行评估NULL
-means-ignore anti-pattern for optional search predicates, in which case **DON'T USE NULL
-means-ignore IN AN PREDICATE!"NULL
-means-ignore 反模式,在这种情况下,**不要在 PREDICATE 中使用NULL
-means-ignore!”
NULL
parameters will be used when some, or even all parameters are NULL
- which is a problem.NULL
参数时将使用相同的缓存执行计划一些,甚至所有参数都是NULL
- 这是一个问题。IQueryable<T>
's Linq extensions and reassigning to itself.IQueryable<T>
的 Linq 扩展并重新分配给自身来构建您的查询。
IQueryable<T> query = db.Etc; query = query.Where( e => etc );
IQueryable<T> query = db.Etc; query = query.Where( e => etc );
IQueryable<T> query = db.Etc; query = query.Where( e => etc );
.Where()
is added as an AND
condition..Where()
都作为AND
条件添加。 If you want to build-up an OR
condition then use PredicateBuilder
.OR
条件,请使用PredicateBuilder
。DateTime filterStart = criteria.FilterStartDate.Date;
DateTime filterEndExcl = criteria.FilterEndDate .Date.AddDays(1);
using (SUPEntities db = new SUPEntities())
{
IQueryable<AssignementMasterData> query = db.AssignementMasterDatas
.Include( m => m.AssignmentNoteIdentifiedClasses )
.Where( m => m.CreatedDateTime >= filterStart )
.Where( m => m.CreatedDateTime < filterEndExcl ) // Exclusive upper-bound.
.Where( m => m.Processed == criteria.Processed )
.Where( m => m.ClassNumber == criteria.ClassNumber )
;
if( criteria.AssigmentNumber != null )
{
query = query.Where( m => m.AssignmentNoteNumber == criteria.AssigmentNumber );
}
if( criteria.AccountNumber != null )
{
query = query.Where( m => m.AccountNumber == criteria.AccountNumber );
}
if( criteria.CourseId != null && criteria.CourseId.Value > 0 )
{
query = query.Where( m => m.BaseCourseId == criteria.CourseId );
}
if( criteria.ReferenceNumber != null )
{
query = query.Where( m => m.ReferenceNumber == criteria.ReferenceNumber );
}
if( criteria.FacultyCode != null )
{
query = query.Where( m => m.FacultyCode == criteria.FacultyCode );
}
if( criteria.ClassNumber != null )
{
query = query.Where( m => m.ClassNumber == criteria.ClassNumber );
}
List<AssignementMasterData> rows = await query.ToListAsync().ConfigureAwait(false);
List<String> categories = rows
.SelectMany( r => r.AssignmentNoteIdentifiedClasses )
.Select( String.IsNullOrEmpty(e.Category)? "(!)": e.Category) )
.ToList();
return categories;
}
The above can be simplified by adding a new extension-method (make sure you use Expression<Func<...>>
and not just Func<>
so that EF can still interpret the query:上面可以通过添加一个新的扩展方法来简化(确保你使用
Expression<Func<...>>
而不仅仅是Func<>
以便 EF 仍然可以解释查询:
public static class MyQueryableExtensions
{
public static IQueryable<T> WhereIfNotNull<T,TValue>( this IQueryable<T> query, TValue? value, Expression<Func<T,Boolean>> predicate )
where TValue : struct
{
if( value.HasValue && value.Value != default(TValue) )
{
return query.Where( predicate );
}
else
{
return query;
}
}
}
Used like so:像这样使用:
// `criteria` is now named `c` for brevity.
DateTime filterStart = c.FilterStartDate.Date;
DateTime filterEndExcl = c.FilterEndDate .Date.AddDays(1);
using (SUPEntities db = new SUPEntities())
{
IQueryable<AssignementMasterData> query = db.AssignementMasterDatas
.Include( m => m.AssignmentNoteIdentifiedClasses )
.Where( m => m.CreatedDateTime >= filterStart )
.Where( m => m.CreatedDateTime < filterEndExcl ) // Exclusive upper-bound.
.Where( m => m.Processed == c.Processed )
.Where( m => m.ClassNumber == c.ClassNumber )
.WhereIfNotNull( c.AssigmentNumber, m => m.AssignmentNoteNumber == c.AssigmentNumber )
.WhereIfNotNull( c.AccountNumber , m => m.AccountNumber == c.AccountNumber )
.WhereIfNotNull( c.CourseId , m => m.BaseCourseId == c.CourseId )
.WhereIfNotNull( c.ReferenceNumber, m => m.ReferenceNumberr == c.ReferenceNumber )
.WhereIfNotNull( c.FacultyCode , m => m.FacultyCoder == c.FacultyCode )
.WhereIfNotNull( c.ClassNumber , m => m.ClassNumber == c.ClassNumber )
;
List<AssignementMasterData> rows = await query.ToListAsync().ConfigureAwait(false);
List<String> categories = rows
.SelectMany( r => r.AssignmentNoteIdentifiedClasses )
.Select( String.IsNullOrEmpty(e.Category)? "(!)": e.Category) )
.ToList();
return categories;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.