鉴于以下简化的Entity Framework 6上下文,我尝试使用实体填充List,但是如何通过反射投射(我相信)有问题。
public class FooContext : DbContext
{
public virtual IDbSet<FooClass> Foo { get; set; }
//...
}
public class FooClass
{
public int Id{ get; set; }
public string Name {get; set; }
//...
}
public main()
{
using (var context = new FooContext())
{
var sets = typeof(FooContext).GetProperties().Where(pi => pi.PropertyType.IsInterface && pi.PropertyType.GetGenericTypeDefinition().ToString().ToLower().Contains("idbset"));
foreach (var set in sets)
{
//When I debug and enumerate over 'value' the entire results are shown so I believe the reflection part is OK.
var value = set.GetValue(context, null);
//Always returns null. How can I cast DbSet<T> to List<object> or List<T>?
var list = value as List<object>();
//...
}
}
}
我正在为实用程序方法执行此操作,以进行一些集成测试。我试图这样做,而不使用直接内联SQL调用(使用SqlConnection和SqlCommand等)来访问数据库(因为数据存储可能会更改为Oracle等)。
答案 0 :(得分:10)
IDBSet继承自IQueryable<TEntity>
,IEnumerable<TEntity>
,IQueryable
和IEnumerable
,因此您无法直接将其投放到列表中。
您可以使用List<TEntity>
或DBSet
.ToList()
中所有实体的.ToListAsync()
个var tileBackground = SKSpriteNode(color: UIColor.whiteColor(), size: CGSizeMake(width: screenWidth, height: screenWidth))
tileBackground.name = "tileBackground"
tileBackground.position = CGPoint(x: frame.midX, y: frame.midY);
self.addChild(tileBackground)
var tile = SKSpriteNode(color: UIColor.redColor(), size: CGSize(width: tileSize, height: tileSize))
tile.name = "tile1"
tileBackground.addChild(tile)
这会创建内存中所有实体的副本,因此您应该考虑直接在DBSet上使用LINQ进行操作
答案 1 :(得分:8)
//dont forget using System.Linq;
using (var context = new FooContext())
{
IQueryable<FooClass> rtn = from temp in context.Foo select temp;
var list = rtn.ToList();
}
答案 2 :(得分:1)
你无法施展它。只需通过List<T>
向您DbSet
创建新的ToListAsync<T>()
即可
从IQueryable
通过异步枚举或简单地同步ToList()
此外,我认为更好地为您的场景创建具体的实现。现在为EF创建。例如,当你开始使用NHibernate时,为它创建测试,依此类推。对于未来的支持将更加简单,然后尝试创建通用的东西,这对于修复和调试来说会更复杂。
仅供参考,您确定不需要这些集成测试吗? 也许更好的测试您的映射/实现正在使用您的数据库。我认为这将是更重要的部分。当然,如果你之前没有这样做过。
答案 3 :(得分:1)
除了VicYam的答案之外,这里有一个更简单的方法,详细说明。
添加System.Linq
命名空间后,您不再需要获取IQueryable
,然后转换为List
。相反,您将在DbSet
对象上获得扩展方法。
这是什么意思?您可以直接返回DbSet
,因为它继承自IEnumerable
。然后,消费者(可能是开发者)可以执行.ToList
或他们可能需要的任何其他列表类型。
<强>最简单强>
这将按原样返回DbSet
,它已经从IEnumerable
继承,这是一种列表类型,然后可以转换为List
。
List<ObjectType> list = new List<ObjectType>();
using (var context = new FooContext())
{
list = context.Foo;
}
<强>替代强>
您可以立即从IEnumerable
转换为List
。
using (var context = new FooContext())
{
var list = context.Foo.ToList();
}
仍然想要VicYam的答案,但作为一条线?
using (var context = new FooContext())
{
var list = context.Foo.AsQueryable().ToList();
}
答案 4 :(得分:0)
<cfset myArray = arrayNew(1)>
<cfloop query="displayQ" >
<cfquery name="fileListQ" datasource="#REQUEST.datasource#">
select
project_id,
doc_id,
file_name,
file_size,
status,
status_date,
timestamp,
upload_date
from project_documents
where
project_id = "#displayQ.project_id#"
<cfif bitAnd(SESSION.rights,structFind(rightsList,"RIGHTS_ADMIN")) EQ 0
AND bitAnd(SESSION.rights,structFind(rightsList,"RIGHTS_ENOVIS_PS")) EQ 0 >
and status = 3
</cfif>
</cfquery>
<cfloop query="fileListQ">
<tr>
<CFSET myArray=ArrayAppend(myArray,#fileListQ.doc_id#,"true"); />
<td><span class="FAKELINK" onClick="doReport('#fileListQ.file_name#','#fileListQ.doc_id#')">
#fileListQ.file_name#
</span>
</td>
</tr>
</cfloop>
</cfloop>
db.StudentDatabaseDbTableModel的类型为DbSet。 ToList是DbSet类中的一个方法。 ToList方法将DbSet类型的对象转换为List类型。