当我尝试向 View 中添加对象时,它抛出异常unable to track an instance of type because it is a query type
。有办法解决这个问题吗?
最佳答案
Query Types根据定义是只读的(对于所有数据库提供程序,不仅限于内存中的):
但是,除了它们通常的使用场景之外,
他们允许
或者换句话说
这是通过ToQuery fluent API实现的:
因此,对于在内存数据库中测试查询类型,您应该利用定义的查询映射功能。
例如,在OnModelCreating
覆盖内,您可以添加以下内容:
if (Database.IsInMemory())
{
// In memory test query type mappings
modelBuilder.Query<MyQueryType>().ToQuery(() => LINQ_query);
// ... similar for other query types
}
else
{
// Database query type mappings
modelBuilder.Query<MyQueryType>().ToView("MyQueryTypeView");
// ...
}
其中
LINQ_query
是访问上下文DbSet
和DbQuery
并投影到MyQueryType
的普通LINQ查询。然后,测试将为涉及的实体提供数据,并且使用
DbQuery
的查询将从定义的查询中检索数据。上面的方法应该是在内存数据库中测试 View 的推荐方法。
仅出于完整性考虑,可以通过创建某种查询存储库直接向
DbQuery
提供数据(基本上是模拟它们),但是有以下限制-必须共享(static
),因为当前EF Core无法正确处理db除了DbSet<T>
和DbQuery<T>
之外的上下文成员(例如全局查询过滤器)。像这样的东西:
public static class FakeQueryProvider
{
static Dictionary<Type, IQueryable> queries = new Dictionary<Type, IQueryable>();
public static void SetQuery<T>(IQueryable<T> query)
{
lock (queries)
queries[typeof(T)] = query;
}
public static IQueryable<T> GetQuery<T>()
{
lock (queries)
return queries.TryGetValue(typeof(T), out var query) ? (IQueryable<T>)query : Enumerable.Empty<T>().AsQueryable();
}
public static QueryTypeBuilder<T> ToFakeQuery<T>(this QueryTypeBuilder<T> builder)
where T : class
{
return builder.ToQuery(() => GetQuery<T>());
}
}
然后代替
.ToQuery(() => LINQ_query);
你会用
.ToFakeQuery();
并像这样将其喂入测试
List<MyQueryType> data = ...;
FakeQueryProvider.SetQuery(data.AsQueryable());
我仍然推荐第一种方法,因为共享存储限制了并行运行
MyQueryType
相关测试的能力。关于c# - 如何使用内存数据库提供程序中的Entity Framework Core测试数据库 View ?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55373825/