提问人:Daniel Ninchev 提问时间:5/12/2022 最后编辑:Svyatoslav DanylivDaniel Ninchev 更新时间:5/13/2022 访问量:338
Collection.AsQueryable() 在使用 AutoMapper 映射时返回 NullReferenceException
Collection.AsQueryable() returns NullReferenceException when mapping with AutoMapper
问:
我对编程还有点陌生。我的 LessonsService 中有以下方法:
public async Task<IEnumerable<T>> GetUserLessonsTableDataAsync<T>(string userId, string sortColumn, string sortColumnDirection, string searchValue)
{
var user = await this.usersRepository
.AllAsNoTracking()
.Include(x => x.Trainer)
.ThenInclude(t => t.Lessons)
.Include(x => x.Member)
.ThenInclude(m => m.Lessons)
.ThenInclude(lm => lm.Lesson)
.FirstOrDefaultAsync(x => x.Id == userId);
IQueryable<Lesson> lessons;
if (user.Trainer != null)
{
lessons = user.Trainer.Lessons.AsQueryable();
}
else
{
var lessonsMembers = user.Member.Lessons.Where(x => x.MemberId == user.MemberId);
var lessonsList = new List<Lesson>();
foreach (var lessonMember in lessonsMembers)
{
lessonsList.Add(lessonMember.Lesson);
}
lessons = lessonsList.AsQueryable();
}
var lessonData = from lesson in lessons select lesson;
if (!(string.IsNullOrEmpty(sortColumn) && string.IsNullOrEmpty(sortColumnDirection)))
{
lessonData = lessonData.OrderBy(sortColumn + " " + sortColumnDirection);
}
if (!string.IsNullOrEmpty(searchValue))
{
lessonData = lessonData.Where(l => l.Topic.Contains(searchValue)
|| l.StartingTime.Equals(searchValue)
|| l.Group.Name.Contains(searchValue)
|| l.Trainer.User.FirstName.Contains(searchValue)
|| l.Trainer.User.LastName.Contains(searchValue));
}
return lessonData.To<T>().ToList();
}
出于某种原因,此代码会引发 System.NullReferenceException,并显示消息“对象引用未设置为对象的实例”。我调试并注意到 lessonData 不是 null,它充满了来自数据库的数据。显然,映射方法.To< T >() 无法正常工作,因为它返回以下内容:
我的控制器是:
[HttpPost]
public async Task<IActionResult> GetUserLessons()
{
try
{
var userId = this.HttpContext.Session.GetString("userId");
var draw = this.Request.Form["draw"].FirstOrDefault();
var start = this.Request.Form["start"].FirstOrDefault();
var length = this.Request.Form["length"].FirstOrDefault();
var sortColumn = this.Request.Form["columns[" + this.Request.Form["order[0][column]"].FirstOrDefault() + "][name]"].FirstOrDefault();
var sortColumnDirection = this.Request.Form["order[0][dir]"].FirstOrDefault();
var searchValue = this.Request.Form["search[value]"].FirstOrDefault();
int pageSize = length != null ? Convert.ToInt32(length) : 0;
int skip = start != null ? Convert.ToInt32(start) : 0;
int recordsTotal = 0;
var lessonData = await this.lessonsService.GetUserLessonsTableDataAsync<LessonViewModel>(userId, sortColumn, sortColumnDirection, searchValue);
recordsTotal = lessonData.Count();
var data = lessonData.Skip(skip).Take(pageSize).ToList();
var jsonData = new { draw, recordsFiltered = recordsTotal, recordsTotal, data };
return this.Ok(jsonData);
}
catch (Exception e)
{
throw;
}
}
堆栈跟踪中的异常消息如下:
at System.Linq.Enumerable.SelectIPartitionIterator`2.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at ChessBurgas64.Services.Data.LessonsService.<GetUserLessonsTableDataAsync>d__15`1.MoveNext() in F:\ChessclubBurgas64WebApp\ChessBurgas64\Services\ChessBurgas64.Services.Data\LessonsService.cs:line 211
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at ChessBurgas64.Web.Controllers.UsersController.<GetUserLessons>d__17.MoveNext() in F:\ChessclubBurgas64WebApp\ChessBurgas64\Web\ChessBurgas64.Web\Controllers\UsersController.cs:line 171
我有一个静态类(其中方法.To< T >() 被定位),在 lessonsService 中引用:
public static class QueryableMappingExtensions
{
public static IQueryable<TDestination> To<TDestination>(
this IQueryable source,
params Expression<Func<TDestination, object>>[] membersToExpand)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
return source.ProjectTo(AutoMapperConfig.MapperInstance.ConfigurationProvider, null, membersToExpand);
}
public static IQueryable<TDestination> To<TDestination>(
this IQueryable source,
object parameters)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
return source.ProjectTo<TDestination>(AutoMapperConfig.MapperInstance.ConfigurationProvider, parameters);
}
}
我注意到这仅发生在导航属性上(在本例中为用户。Trainer.Lessons))。 如果我直接从存储库中获取课程,lessons = this.lessonsRepository.All()。Where(...);,不会有问题,一切都会正常工作,因为集合将是 Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable 而不是 System.Collections.Generic.HashSet'1[Lesson]。所以我想问题在于方法.AsQueryable() 并没有真正将课程转换为 Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable,这是映射方法所必需的。要< >() 才能正常工作?解决此问题的最佳方法是什么?
答: 暂无答案
评论
Exception.ToString()
Include
AllAsNoTracking