使用EntityFramework中DbSet.Set(Type entityType)方法碰到的问题
使用的是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)方法碰到的问题的更多相关文章
- EntityFramework 中支持 BulkInsert 扩展
本文为 Dennis Gao 原创技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载. 前言 很显然,你应该不至于使用 EntityFramework 直接插入 10W 数据到数据库中,那 ...
- EntityFramework中支持BulkInsert扩展(转载)
前言 很显然,你应该不至于使用 EntityFramework 直接插入 10W 数据到数据库中,那可能得用上个几分钟.EntityFramework 最被人诟病的地方就是它的性能,处理大量数据时的效 ...
- EntityFramework中支持BulkInsert扩展
EntityFramework中支持BulkInsert扩展 本文为 Dennis Gao 原创技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载. 前言 很显然,你应该不至于使用 Ent ...
- MVC中使用Entity Framework 基于方法的查询学习笔记 (二)
解释,不解释: 紧接上文,我们在Visual Studio2012中看到系统为我们自动创建的视图(View)文件Index.cshtml中,开头有如下这句话: @model IEnumerable&l ...
- 解析Jquery取得iframe中元素的几种方法
iframe在复合文档中经常用到,利用jquery操作iframe可以大幅提高效率,这里收集一些基本操作,需要的朋友可以参考下 DOM方法:父窗口操作IFRAME:window.frames[&q ...
- 在html中添加script脚本的方法和注意事项
在html中添加script脚本有两种方法,直接将javascript代码添加到html中与添加外部js文件,这两种方法都比较常用,大家可以根据自己需要自由选择 在html中添加<script& ...
- jquery中prop()方法和attr()方法的区别浅析
官方例举的例子感觉和attr()差不多,也不知道有什么区别,既然有了prop()这个新方法,不可能没用吧,那什么时候该用attr(),什么时候该用prop()呢 jquery1.6中新加了一个方法pr ...
- Python中optionParser模块的使用方法[转]
本文以实例形式较为详尽的讲述了Python中optionParser模块的使用方法,对于深入学习Python有很好的借鉴价值.分享给大家供大家参考之用.具体分析如下: 一般来说,Python中有两个内 ...
- EntityFramework中的线程安全,又是Dictionary
继上次记一次w3wp占用CPU过高的解决过程(Dictionary和线程安全)后又再次与Dictionary博弈,这一次是在EntityFramework中的Dictionary. 从一个异常说起 这 ...
随机推荐
- Android自定义控件之TextView
转自:http://labs.easymobi.cn/?p=284 有时候Android自带的控件无法满足我们的某些要求,这时就需要我们自定义控件来实现这些功能.比如需要一个TextView里的字倾斜 ...
- xamarin mac 之 资料
中文社区 xamarin.form 30天学习计划
- Javascript 浮点运算问题分析与解决
分析 JavaScript 只有一种数字类型 Number ,而且在Javascript中所有的数字都是以IEEE-754标准格式表示的. 浮点数的精度问题不是JavaScript特有的,因为有些小数 ...
- gec210 NAND BOOT与SD BOOT启动原理
CPU上电后,此时SP指针指向0x0000_0000,从这个地址取第一条指令.但此时:PLL没有启动,CPU工作频率为外部输入晶振频率,非常低(S5PV210中晶振在CPU旁边,两颗24MHz,一颗2 ...
- grunt安装详解及失败处理
标签: 1.官网 nodejs官网 https://nodejs.org/en/ Grunt官网 http://gruntjs.com/ Grunt插件首页 http://gruntjs.com/p ...
- js模块化开发——require.js的用法详细介绍(含jsonp)
RequireJS的目标是鼓励代码的模块化,它使用了不同于传统<script>标签脚本加载步骤.可以用它回事.优化代码,但其主要的目的还是为了代码的模块化.它鼓励在使用脚本以moudle ...
- sqlloader外部表
一创建目录 先在系统下创建 $ cd /home/oracle $ mkdir dir $ cd dir $ pwd 再在sqlplus里创建,让oracle知道这个目录 SQL> create ...
- WPF 实现验证码功能
产生验证码的类:ValidCode.cs public class ValidCode { #region Private Fields /// <summary> /// PI /// ...
- jQuery克隆DOM节点
jQuery克隆DOM节点 <%@ page language="java" import="java.util.*" pageEncoding=&quo ...
- .md即markdown文件的基本常用编写语法(图文并茂)
序言: 很久没有写博客了,感觉只要是不写博客,人就很变得很懒,学的知识点感觉还是记不住,渐渐地让我明白,看的越多,懂的越少(你这话不是有毛病吗?应该是看的越多,懂的越多才对),此话怎讲,当你在茫茫的前 ...