如何在匿名方法中将DBSet转换为接口--E.F

时间:2013-03-21 22:48:50

标签: c# asp.net-mvc entity-framework interface anonymous-function

我的SQL DB中有许多用于存储基本KVP数据的表。它们都具有Id(int),Description(varchar(..))的模式。

我在MVC应用程序中的一个阶段或另一个阶段都需要它们,我正在尝试创建一个匿名方法,该方法将采用实体类的类型并返回该项数据的列表。我希望能够将此方法用于我的数据库中的任意数量的表,而不必过多地扩展我写的方法。

示例数据:

  • Id:1,说明:红色
  • Id:2,说明:蓝色
  • Id:3,说明:绿色

ISet实施:

public interface ISet
{
    int Id { get; set; }
    string Description { get; set; }
}

可能的方法实施

public static IList<T> BuildSet<T>()
{
    using (var db = new somethingEntities())
        return db.Set(typeof(T)).Cast<ISet>().Select(c => new { c.Id, c.Description }).ToList();
}

用法

var data = BuildSet<YourType>();

运行时错误

Cannot create a DbSet<ISet> from a non-generic DbSet for objects of type 'YourType'.

有谁知道怎么做?

感谢。

2 个答案:

答案 0 :(得分:0)

问题解决了。

方法声明

public static List<ISet> BuildSet<T>() where T : class
{
    using (var db = new somethingEntities())
        return db.Set<T>().ToList().Cast<ISet>().ToList();
}

<强>用法

var data = ...BuildSet<YourType>();

答案 1 :(得分:0)

我认为DbSet很小,因为ToList()会一次性获取所有结果吗?

但是,这是一个更简单的代码版本(在泛型类型约束中指定接口ISet):

public static IList<ISet> BuildSet<T>() 
    where T : class, ISet
{
    using (var db = new somethingEntities())
        return db.Set<T>().ToList();
}

还可以选择DbContext的扩展方法:

public IEnumerable<ISet> BuildSet<T>(this DbContext context)
    where T : class, ISet
{
    return context.Set<T>().AsEnumerable();
}

然后您可以在上下文的生命周期内使用,可以实现更高效的操作。 (我知道我假设太多,但无论如何我觉得这是有用的信息。)

public void SomeOperation()
{
    using (var db = new somethingEntities())
    {
        foreach (var item in db.BuildSet<SimpleSet>())
        {
            //do something with item
            //SaveChanges() every 100 rows or whatever
        }
    }
}