这是检索数据的正确方法吗?这是我能够为用户检索具有相应类别的所有任务的唯一方法。如果我在.ToList()之前有where子句,它会给我一个异常(ApplicationUser将为null)。我不喜欢这种方法是我首先从数据库中检索所有数据,然后再解析它以仅为特定用户返回数据。对于某些情况,.Include()方法不能正常工作。
public IEnumerable<Task> GetAllTasksForUser(string username)
{
return _db.Tasks
.Include(t => t.Category)
.Include(t => t.Category.ApplicationUser)
.ToList()
.Where(t => t.Category.ApplicationUser.UserName == username);
}
这个错误:
try
{
var x = _db.Tasks
.Include(t => t.Category)
.Include(t => t.Category.ApplicationUser)
.Where(t => t.Category.ApplicationUser.UserName == username)
.ToList();
}
catch(Exception ex)
{
}
从Profiler检索生成的工作sql语句。当我运行生成的查询时,它会检索数据,但它会抛出linq提到的异常。这个.Include()正在杀了我:
> SELECT [t].[TaskId], [t].[CategoryId], [t].[Description], [t].[Name], [t].[Timestamp], [t.Category].[CategoryId], [t.Category].[Description], [t.Category].[Name], [t.Category].[Timestamp], [t.Category].[UserId], [t.Category.ApplicationUser].[Id], [t.Category.ApplicationUser].[AccessFailedCount], [t.Category.ApplicationUser].[ConcurrencyStamp], [t.Category.ApplicationUser].[Email], [t.Category.ApplicationUser].[EmailConfirmed], [t.Category.ApplicationUser].[LockoutEnabled], [t.Category.ApplicationUser].[LockoutEnd], [t.Category.ApplicationUser].[NormalizedEmail], [t.Category.ApplicationUser].[NormalizedUserName], [t.Category.ApplicationUser].[PasswordHash], [t.Category.ApplicationUser].[PhoneNumber], [t.Category.ApplicationUser].[PhoneNumberConfirmed], [t.Category.ApplicationUser].[SecurityStamp], [t.Category.ApplicationUser].[TwoFactorEnabled], [t.Category.ApplicationUser].[UserName], [c].[CategoryId], [c].[Description], [c].[Name], [c].[Timestamp], [c].[UserId], [a].[Id], [a].[AccessFailedCount], [a].[ConcurrencyStamp], [a].[Email], [a].[EmailConfirmed], [a].[LockoutEnabled], [a].[LockoutEnd], [a].[NormalizedEmail], [a].[NormalizedUserName], [a].[PasswordHash], [a].[PhoneNumber], [a].[PhoneNumberConfirmed], [a].[SecurityStamp], [a].[TwoFactorEnabled], [a].[UserName], [c0].[CategoryId], [c0].[Description], [c0].[Name], [c0].[Timestamp], [c0].[UserId]
FROM [Tasks] AS [t]
INNER JOIN [Categories] AS [t.Category] ON [t].[CategoryId] = [t.Category].[CategoryId]
LEFT JOIN [AspNetUsers] AS [t.Category.ApplicationUser] ON [t.Category].[UserId] = [t.Category.ApplicationUser].[Id]
INNER JOIN [Categories] AS [c] ON [t].[CategoryId] = [c].[CategoryId]
LEFT JOIN [AspNetUsers] AS [a] ON [c].[UserId] = [a].[Id]
INNER JOIN [Categories] AS [c0] ON [t].[CategoryId] = [c0].[CategoryId]
ORDER BY [t.Category].[UserId]
这个有效,但结果不包括Category和ApplicationUser:
return _db.Tasks
.Where(t => t.Category.ApplicationUser.UserName == username)
.ToList();
我的模特:
public class Task
{
[Key]
public int TaskId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public DateTime Timestamp { get; set; }
public int CategoryId { get; set; }
public virtual Category Category { get; set; }
}
public class Category
{
[Key]
public int CategoryId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public DateTime Timestamp { get; set; }
public string UserId { get; set; }
[ForeignKey("UserId")]
public virtual ApplicationUser ApplicationUser { get; set; }
public virtual ICollection<Task> Tasks { get; set; }
}
public class ApplicationUser : IdentityUser
{
public virtual ICollection<Category> Categories { get; set; }
}
错误堆栈跟踪:
在lambda_method(Closure,InternalEntityEntry) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.SimpleNonNullableDependentKeyValueFactory
1.TryCreateFromCurrentValues(InternalEntityEntry entry, TKey& key) at Microsoft.EntityFrameworkCore.Query.Internal.WeakReferenceIdentityMap
1.CreateIncludeKeyComparer(INAVigation navigation,InternalEntityEntry entry) 在Microsoft.EntityFrameworkCore.Query.Internal.QueryBuffer.IncludeCore(对象实体,导航导航) 在Microsoft.EntityFrameworkCore.Query.Internal.QueryBuffer.Include(QueryContext queryContext,Object entity,IReadOnlyList1 navigationPath, IReadOnlyList
1 relatedEntitiesLoaders,Int32 currentNavigationIndex,Boolean queryStateManager) 在Microsoft.EntityFrameworkCore.Query.Internal.QueryBuffer.Include(QueryContext queryContext,Object entity,IReadOnlyList1 navigationPath, IReadOnlyList
1 relatedEntitiesLoaders,Boolean queryStateManager) 在Microsoft.EntityFrameworkCore.Query.Internal.GroupJoinInclude.Include(Object entity) 在Microsoft.EntityFrameworkCore.Query.Internal.GroupJoinInclude.Include(Object entity) 在Microsoft.EntityFrameworkCore.Query.QueryMethodProvider。&lt; _GroupJoin&gt; d__264.MoveNext() at System.Linq.Enumerable.<SelectManyIterator>d__163
3.MoveNext() 在System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext() at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.<_TrackEntities>d__15
2.MoveNext() 在Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.ExceptionInterceptor1.EnumeratorExceptionInterceptor.MoveNext() at System.Collections.Generic.List
1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable
1 source) at .GetAllTasksForUser(String username)in:第31行
答案 0 :(得分:0)
您是否错过了Category实体中ApplicationUser的外键?您只需要为ApplicationUser定义导航属性。尝试设置这种关系; IMO,设置此关系后,错误输出的查询将正常工作。