使用的是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. Android自定义控件之TextView

    转自:http://labs.easymobi.cn/?p=284 有时候Android自带的控件无法满足我们的某些要求,这时就需要我们自定义控件来实现这些功能.比如需要一个TextView里的字倾斜 ...

  2. xamarin mac 之 资料

    中文社区 xamarin.form 30天学习计划

  3. Javascript 浮点运算问题分析与解决

    分析 JavaScript 只有一种数字类型 Number ,而且在Javascript中所有的数字都是以IEEE-754标准格式表示的. 浮点数的精度问题不是JavaScript特有的,因为有些小数 ...

  4. gec210 NAND BOOT与SD BOOT启动原理

    CPU上电后,此时SP指针指向0x0000_0000,从这个地址取第一条指令.但此时:PLL没有启动,CPU工作频率为外部输入晶振频率,非常低(S5PV210中晶振在CPU旁边,两颗24MHz,一颗2 ...

  5. grunt安装详解及失败处理

    标签: 1.官网 nodejs官网 https://nodejs.org/en/ Grunt官网 http://gruntjs.com/ Grunt插件首页  http://gruntjs.com/p ...

  6. js模块化开发——require.js的用法详细介绍(含jsonp)

    RequireJS的目标是鼓励代码的模块化,它使用了不同于传统<script>标签脚本加载步骤.可以用它回事.优化代码,但其主要的目的还是为了代码的模块化.它鼓励在使用脚本以moudle ...

  7. sqlloader外部表

    一创建目录 先在系统下创建 $ cd /home/oracle $ mkdir dir $ cd dir $ pwd 再在sqlplus里创建,让oracle知道这个目录 SQL> create ...

  8. WPF 实现验证码功能

    产生验证码的类:ValidCode.cs public class ValidCode { #region Private Fields /// <summary> /// PI /// ...

  9. jQuery克隆DOM节点

    jQuery克隆DOM节点 <%@ page language="java" import="java.util.*" pageEncoding=&quo ...

  10. .md即markdown文件的基本常用编写语法(图文并茂)

    序言: 很久没有写博客了,感觉只要是不写博客,人就很变得很懒,学的知识点感觉还是记不住,渐渐地让我明白,看的越多,懂的越少(你这话不是有毛病吗?应该是看的越多,懂的越多才对),此话怎讲,当你在茫茫的前 ...