使用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. 从一个异常说起 这 ...
随机推荐
- HTML 表单元素之 input 元素
介绍HTML 5: 表单元素之 input 元素 表单元素之 input 元素 - text, password, url, telephone, email, search, file, radio ...
- 创建sqlserver函数
CREATE FUNCTION getsort (@first varchar(100),@second varchar(100))RETURNS intASBEGIN declare @rv in ...
- oracle系列--解锁数据库
一.安装完成后解锁Scott数据库步骤: 进入SQL Plus 请输入用户名:sys输入口令:sys as sysdba //这里的口令是不可见的,注意空格SQL> alter user sc ...
- PHP根据设备类型自动跳转相应网址页面,这个现在实用
现在移动设备上网也很方便,比如Android智能手机,iPhone/iPad等,很多网站都相继推出了针对电脑和这些手机等移动设备访问的网页,如果你的系统是用PHP写的,那面本代码对你会很实用,可根据这 ...
- Selenium2(java)selenium常用API 五
上传文件 元素标签是input时上传方式 上传是一个input,对于这种元素是input 的标签可以采用元素的sendKeys()方法来直接赋值,upload.html代码: <html&g ...
- php session 生命周期代码实例
php session 生命周期代码实例 我们为什么需要Session,就是因为我们需要存储各个用户的状态数据.那么试问,如果由你来设计解决这个需求的方案,那么也许你会设置这样一个数据 ...
- Raphael的transform用法
Raphael的transform用法 <%@ page language="java" contentType="text/html; charset=UTF-8 ...
- easyui message show中msg嵌入一个按钮如何绑定事件
http://www.oschina.net/question/945028_171927
- javaScript基础详解(1)
javaScript基础详解 首先讲javaScript的摆放位置:<script> 与 </script> 可以放在head和body之间,也可以body中或者head中 J ...
- 没有苹果电脑打包iOS平台的 Ionic 2程序——《Ionic 2 实例开发》更新内容
没有苹果电脑打包iOS平台的 Ionic 2程序--<Ionic 2 实例开发>更新内容春节刚过,祝各位新的一年里万事如意,一帆风顺.<Ionic 2 实例开发>在这段时间里更 ...