使用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. 从一个异常说起 这 ...
随机推荐
- UVa 10132 - File Fragmentation
题目大意:有n个相同的文件,每个文件从中间分为两半,现在给你这2n个文件碎片,求原来完整的文件. 找出文件碎片长度的最大值和最小值,二者相加可得到原来文件的长度len.然后逐个进行拼接,将拼接后长度等 ...
- PHP文件上传和文件操作案例
<?php /* *文件配置变量$dirname是目录名称 */ session_start(); $dirname = 'upload'; $fileClass = new fileClass ...
- 建立、配置和使用Activity——启动、关闭Activity
一个Android应用通常都会包含多个Activity,但只有一个Activity会作为程序的入口——当该Android应用运行时将会自启动并执行该Activity.至于应用中的其他Activity, ...
- #图# #最大生成树# #kruskal# ----- OpenJudge 799:Heavy Transportation
OpenJudge 799:Heavy Transportation 总时间限制: 3000ms 内存限制: 65536kB 描述BackgroundHugo Heavy is happy. Afte ...
- WPF dataGrid中的check的改变事件
关于datagrid信息: <DataGridTemplateColumn Header="备注"> <DataGridTemplateColumn.CellTe ...
- Refused to set unsafe header "Connection"
参考 http://stackoverflow.com/questions/7210507/ajax-post-error-refused-to-set-unsafe-header-connectio ...
- javascript 终止函数执行操作
1.如果终止一个函数的用return即可,实例如下:function testA(){ alert('a'); alert('b'); alert('c');}testA(); 程序 ...
- localStorage 如何存储JSON数据并读取JSON数据
localStorage是HTML5提供的再客户端实现本地存储的一种方法,但是localStorage方法只能存储字符串数据,有时候我们需要存储对象到本地比如:JSON:那么,localStorage ...
- 【物联网云端对接-1】 通过HTTP协议与微软Azure IoT hub进行云端通信
在2015年曾写过一篇文章<从微软build 2015,展望微软未来发展>,提到了微软的Azure和Windows 10 IoT,那算是初次接触微软物联网技术.比较幸运的是在后续的时间里, ...
- Codeforces Round #396 (Div. 2)
C. Mahmoud and a Message time limit per test 2 seconds memory limit per test 256 megabytes input sta ...