使用DbSet从接口转换为特定类

时间:2018-02-12 09:51:55

标签: c# entity-framework casting

假设我有以下代码:

public interface IInterface
{
    string Name { get; set; }
}

public class Foo : IInterface
{
    public string Name { get; set; }
}

public class Bar : IInterface
{
    public string Name { get; set; }
}

///

public class Service
{
    private List<Foo> MyList();
    public IQueryable<Foo> GetObjects()
    {
        return MyList().AsQueryable();
    }

    public IQueryable<Bar> GetObjectsFromBD()
    {
        return Entities.Bar;
    }
}

这就是我将如何使用它

public IQueryable<IInterface> GetFooBars()
{
    var foobars = new IQueryable<IInterface>();
    if(someStuff)
        foobars = service.GetObjects(); /*From cache*/
    else
        foobars = service.GetObjectsFromBD(); /*From DbSet*/
    return foobars;
}

出于某种原因,如果来源是数据库,我想稍后进行特定处理。所以我试着扮演Foo

var query = GetFooBars();
var casted = query as IQueryable<Foo>;
if(casted == null) /*Coming from DB*/
    /*Some conditions*/
else /*Coming from cache*/
    /*Some other conditions*/

但由于某种原因,我忽略casted始终为空,无论它是否来自数据库。

如果我尝试使用某些query.GetType()进行调试,则会产生

 System.Data.Entity.Infrastructure.DbQuery`1[MyNamespace.IInterface]

我错过了什么?如何在不枚举查询的情况下实现我想要做的事情?

1 个答案:

答案 0 :(得分:1)

第一个问题:要检查查询是否来自数据库,您需要检查DbQuery,而不是IQueryable(因为两个方法都返回IQueryable,但只返回数据库方法返回DbQuery):

var query = GetFooBars();
var casted = query as DbQuery<Foo>;
if(casted == null) // *not* from database!

第二个问题:您的方法无法返回DbQuery<Foo>甚至IQueryable<Foo> - 它会返回IQueryable<IInterface>。虽然您的集合实际上是Foo的集合,但类型系统并不知道。所以正确的代码是:

var query = GetFooBars();
var casted = query as DbQuery<IInterface>;
if(casted == null) //...