使用的是EntityFramework, Version=6.0.0.0,项目原本直接将EntityFramework的Entity拿到UI使用,后面想使用dto对象将数据库的Entity与前台分离开,中间使用AutoMapper类的工具进行转换,而原本的一些EntityFramework泛型方法却出现问题了,比如有个基类的方法是这样的:

public abstract class ServiceBase<T> : IServiceBase<T> where T : BaseEntity, new()
{
protected DefaultDataContext NewDB()
{
return new DefaultDataContext();
} public void Add(T entity)
{
using (var db = this.NewDB())
{
db.Entry<T>(entity).State = EntityState.Added;
db.SaveChanges();
}
} public void Modify(T entity)
{
entity.LastUpdatedTime = DateTime.Now;
using (var db = this.NewDB())
{
db.Entry<T>(entity).State = EntityState.Modified;
db.SaveChanges();
}
} public void Delete(string id)
{
using (var db = this.NewDB())
{
var entity = new T() { Id = id };
db.Entry<T>(entity).State = EntityState.Deleted;
db.SaveChanges();
}
} public T GetByID(string id)
{
using (var db = this.NewDB())
{
return db.Set<T>().AsNoTracking().Where(p => p.Id == id).FirstOrDefault();
}
} public IList<T> GetByQuery(BaseQuery query)
{
using (var db = this.NewDB())
{
var pageQuery = db.Set<T>().AsNoTracking().OrderBy(p => p.CreatedTime);
query.TotalRecordCount = pageQuery.Count();
return pageQuery.Page(query.PageIndex, query.PageSize).ToList();
}
}
}

原本泛型T直接传入的是EntityFramework的实体,使用起来是没问题的,但是现在由于从接口方面进行的隔离,所以继承的接口泛型就不能是数据库的实体泛型T了,而变成dto的泛型TDto:

public abstract class ServiceBase<TDto> : IServiceBase<TDto> where TDto : BaseEntity, new()
{}

而Entity与Dto的对应关系,已经用列表存储起来,用来初始化AutoMapper映射工具:

class MapMember
{
public MapMember(Type from, Type to, bool isTwoWay = true)
{
From = from;
To = to;
IsTwoWay = isTwoWay;
} public Type From { set; get; }
public Type To { set; get; }
public bool IsTwoWay { set; get; }
}

按原本的设想,应该直接小改一下原来的代码就可以的,因为EntityFramework的DbContext中,同时提供了DbSet<TEntity> Set<TEntity>() 以及 DbSet Set(Type entityType) ,正常看来,两个方法应该能返回一样的对象进行调用,但是实际使用的时候发现不同了,使用DbSet Set(Type entityType)返回的对象,无法正常调用上述的方法,经过一番搜索,发现两个方法返回的对象存在差异,有看到类似使用.Cast解决方法,虽然编译能过,但是运行的时候会报错。

后面换了个思路,在已知Type的情况下,如何调用泛型<T>方法,暂时找到了一个解决方法:

        public IList<TDto> GetByQuery(BaseQuery query)
{
Type l_entityType = DtoExtensions.GetMapType<TDto>();
dynamic l_entity = l_entityType.Assembly.CreateInstance(l_entityType.FullName); using (var db = NewDB())
{
return DbBaseQueryToList(l_entity, db, query);
}
}
private IList<TDto> DbBaseQueryToList<TEntity>(TEntity tEntity, DefaultDbContext db, BaseQuery query) where TEntity : BaseEntity
{
var l_pageQuery = new FromDbSet<TEntity>(tEntity, db).m_fromDbSet.AsNoTracking().OrderBy(p=>p.CreatedTime);
return l_pageQuery.Page(query.PageIndex, query.PageSize).ToList().ToMapList<TDto>();
}
    public class FromDbSet<T> where T : BaseEntity
{
public DbSet<T> m_fromDbSet; public FromDbSet(T o, DefaultDbContext db)
{
if (o.GetType() == typeof(BaseEntity))
throw new NotSupportedException("不支持基类");
m_fromDbSet = db.Set<T>();
}
}

测试运行了一下,终于不会报错了。不过中间多了这么些步骤估计是会影响效率的,目前来说影响不大,而且也可以通过重写的方式覆盖掉泛型方法,所以先就这样了。如果您有更好的解决方式欢迎提出来共同探讨!

使用EntityFramework中DbSet.Set(Type entityType)方法碰到的问题的更多相关文章

  1. EntityFramework 中支持 BulkInsert 扩展

    本文为 Dennis Gao 原创技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载. 前言 很显然,你应该不至于使用 EntityFramework 直接插入 10W 数据到数据库中,那 ...

  2. EntityFramework中支持BulkInsert扩展(转载)

    前言 很显然,你应该不至于使用 EntityFramework 直接插入 10W 数据到数据库中,那可能得用上个几分钟.EntityFramework 最被人诟病的地方就是它的性能,处理大量数据时的效 ...

  3. EntityFramework中支持BulkInsert扩展

    EntityFramework中支持BulkInsert扩展 本文为 Dennis Gao 原创技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载. 前言 很显然,你应该不至于使用 Ent ...

  4. MVC中使用Entity Framework 基于方法的查询学习笔记 (二)

    解释,不解释: 紧接上文,我们在Visual Studio2012中看到系统为我们自动创建的视图(View)文件Index.cshtml中,开头有如下这句话: @model IEnumerable&l ...

  5. 解析Jquery取得iframe中元素的几种方法

    iframe在复合文档中经常用到,利用jquery操作iframe可以大幅提高效率,这里收集一些基本操作,需要的朋友可以参考下   DOM方法:父窗口操作IFRAME:window.frames[&q ...

  6. 在html中添加script脚本的方法和注意事项

    在html中添加script脚本有两种方法,直接将javascript代码添加到html中与添加外部js文件,这两种方法都比较常用,大家可以根据自己需要自由选择 在html中添加<script& ...

  7. jquery中prop()方法和attr()方法的区别浅析

    官方例举的例子感觉和attr()差不多,也不知道有什么区别,既然有了prop()这个新方法,不可能没用吧,那什么时候该用attr(),什么时候该用prop()呢 jquery1.6中新加了一个方法pr ...

  8. Python中optionParser模块的使用方法[转]

    本文以实例形式较为详尽的讲述了Python中optionParser模块的使用方法,对于深入学习Python有很好的借鉴价值.分享给大家供大家参考之用.具体分析如下: 一般来说,Python中有两个内 ...

  9. EntityFramework中的线程安全,又是Dictionary

    继上次记一次w3wp占用CPU过高的解决过程(Dictionary和线程安全)后又再次与Dictionary博弈,这一次是在EntityFramework中的Dictionary. 从一个异常说起 这 ...

随机推荐

  1. HTML 表单元素之 input 元素

    介绍HTML 5: 表单元素之 input 元素 表单元素之 input 元素 - text, password, url, telephone, email, search, file, radio ...

  2. 创建sqlserver函数

    CREATE FUNCTION getsort (@first varchar(100),@second varchar(100))RETURNS  intASBEGIN declare @rv in ...

  3. oracle系列--解锁数据库

    一.安装完成后解锁Scott数据库步骤: 进入SQL Plus 请输入用户名:sys输入口令:sys as sysdba  //这里的口令是不可见的,注意空格SQL> alter user sc ...

  4. PHP根据设备类型自动跳转相应网址页面,这个现在实用

    现在移动设备上网也很方便,比如Android智能手机,iPhone/iPad等,很多网站都相继推出了针对电脑和这些手机等移动设备访问的网页,如果你的系统是用PHP写的,那面本代码对你会很实用,可根据这 ...

  5. Selenium2(java)selenium常用API 五

    上传文件   元素标签是input时上传方式 上传是一个input,对于这种元素是input 的标签可以采用元素的sendKeys()方法来直接赋值,upload.html代码: <html&g ...

  6. php session 生命周期代码实例

     php session 生命周期代码实例        我们为什么需要Session,就是因为我们需要存储各个用户的状态数据.那么试问,如果由你来设计解决这个需求的方案,那么也许你会设置这样一个数据 ...

  7. Raphael的transform用法

    Raphael的transform用法 <%@ page language="java" contentType="text/html; charset=UTF-8 ...

  8. easyui message show中msg嵌入一个按钮如何绑定事件

    http://www.oschina.net/question/945028_171927

  9. javaScript基础详解(1)

    javaScript基础详解 首先讲javaScript的摆放位置:<script> 与 </script> 可以放在head和body之间,也可以body中或者head中 J ...

  10. 没有苹果电脑打包iOS平台的 Ionic 2程序——《Ionic 2 实例开发》更新内容

    没有苹果电脑打包iOS平台的 Ionic 2程序--<Ionic 2 实例开发>更新内容春节刚过,祝各位新的一年里万事如意,一帆风顺.<Ionic 2 实例开发>在这段时间里更 ...