博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用EntityFramework中DbSet.Set(Type entityType)方法碰到的问题
阅读量:5918 次
发布时间:2019-06-19

本文共 3851 字,大约阅读时间需要 12 分钟。

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

public abstract class ServiceBase
: IServiceBase
where T : BaseEntity, new() { protected DefaultDataContext NewDB() { return new DefaultDataContext(); } public void Add(T entity) { using (var db = this.NewDB()) { db.Entry
(entity).State = EntityState.Added; db.SaveChanges(); } } public void Modify(T entity) { entity.LastUpdatedTime = DateTime.Now; using (var db = this.NewDB()) { db.Entry
(entity).State = EntityState.Modified; db.SaveChanges(); } } public void Delete(string id) { using (var db = this.NewDB()) { var entity = new T() { Id = id }; db.Entry
(entity).State = EntityState.Deleted; db.SaveChanges(); } } public T GetByID(string id) { using (var db = this.NewDB()) { return db.Set
().AsNoTracking().Where(p => p.Id == id).FirstOrDefault(); } } public IList
GetByQuery(BaseQuery query) { using (var db = this.NewDB()) { var pageQuery = db.Set
().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
: IServiceBase
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
GetByQuery(BaseQuery query) { Type l_entityType = DtoExtensions.GetMapType
(); dynamic l_entity = l_entityType.Assembly.CreateInstance(l_entityType.FullName); using (var db = NewDB()) { return DbBaseQueryToList(l_entity, db, query); } } private IList
DbBaseQueryToList
(TEntity tEntity, DefaultDbContext db, BaseQuery query) where TEntity : BaseEntity { var l_pageQuery = new FromDbSet
(tEntity, db).m_fromDbSet.AsNoTracking().OrderBy(p=>p.CreatedTime); return l_pageQuery.Page(query.PageIndex, query.PageSize).ToList().ToMapList
(); }
public class FromDbSet
where T : BaseEntity { public DbSet
m_fromDbSet; public FromDbSet(T o, DefaultDbContext db) { if (o.GetType() == typeof(BaseEntity)) throw new NotSupportedException("不支持基类"); m_fromDbSet = db.Set
(); } }

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

转载于:https://www.cnblogs.com/PFly/p/6478515.html

你可能感兴趣的文章
Ubuntu 配置java环境变量
查看>>
JQuery UI - tabs
查看>>
innerHTML与innerText的异同
查看>>
初探单点登录 SSO
查看>>
[转]iOS WebKit browsers and auto-zooming form controls
查看>>
Python基础(2)--对象类型
查看>>
禁止在工作流设计器启动持续活动的重新编译
查看>>
KVO的使用
查看>>
Linux内核RPC请求过程
查看>>
An interview question from MicroStrategy
查看>>
Spring4 MVC Hibernate4集成
查看>>
实习求职小结
查看>>
java Comparable和Comaprator的对比
查看>>
[CLR via C#]13. 接口
查看>>
Orchard之生成新模板
查看>>
博客园为我们提供的函数
查看>>
C#枚举
查看>>
大话Linux内核中锁机制之完成量、互斥量
查看>>
codeblocks中添加-std=c99
查看>>
tomcat配置虚拟主机
查看>>