zoukankan      html  css  js  c++  java
  • 使用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>();
            }
        }

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

  • 相关阅读:
    SharePoint 2013 配置基于表单的身份认证
    SharePoint 2013 场解决方案包含第三方程序集
    SharePoint 2010 站点附加数据升级到SP2013
    SharePoint 2013 在母版页中插入WebPart
    SharePoint 2013 搭建负载均衡(NLB)
    SharePoint 部署解决方案Feature ID冲突
    SharePoint 2013 配置基于AD的Form认证
    SharePoint Server 2016 Update
    SharePoint 2013 为用户组自定义EventReceiver
    SharePoint 2013 JavaScript API 记录
  • 原文地址:https://www.cnblogs.com/PFly/p/6478515.html
Copyright © 2011-2022 走看看