在讲解之前,先来看看解决方案的架构:


1、在Nop.Core下的Domain里建立一个实体Category;
2、在Nop.Data下的Mapping\Catatog\下建立一个数据表映射CategoryMap:
using System.Data.Entity.ModelConfiguration;
using Nop.Core.Domain.Catalog;

namespace Nop.Data.Mapping.Catalog
{
    public partial class CategoryMap : EntityTypeConfiguration<Category>
    {
        public CategoryMap()
        {
            this.ToTable("Category");
            this.HasKey(c => c.Id);
            this.Property(c => c.Name).IsRequired().HasMaxLength(400);
            this.Property(c => c.Description).IsMaxLength();
            this.Property(c => c.MetaKeywords).HasMaxLength(400);
            this.Property(c => c.MetaDescription);
            this.Property(c => c.MetaTitle).HasMaxLength(400);
            this.Property(c => c.SeName).HasMaxLength(200);
            this.Property(c => c.PriceRanges).HasMaxLength(400);
            this.Property(c => c.PageSizeOptions).HasMaxLength(200);
        }
    }
}
3、在Nop.Data下建EF上下文接口IDbContext和对象NopObjectContext:
IDbContext:
using System.Collections.Generic;
using System.Data.Entity;
using Nop.Core;

namespace Nop.Data
{
    public interface IDbContext
    {
        IDbSet<TEntity> Set<TEntity>() where TEntity : BaseEntity;

int SaveChanges();

IList<TEntity> ExecuteStoredProcedureList<TEntity>(string commandText, params object[] parameters)
            where TEntity : BaseEntity, new();
    }
}

NopObjectContext:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.ModelConfiguration;
using System.Linq;
using System.Reflection;
using Nop.Core;
using Nop.Core.Domain.Catalog;
using Nop.Data.Mapping.Catalog;
//using Nop.Data.Mapping.Localization;

namespace Nop.Data
{
    /// <summary>
    /// Object context
    /// </summary>
    public class NopObjectContext : DbContext, IDbContext
    {
        public NopObjectContext(string nameOrConnectionString)
            : base(nameOrConnectionString)
        {
            //((IObjectContextAdapter) this).ObjectContext.ContextOptions.LazyLoadingEnabled = true;
        }
        //public DbSet<Category> Category { get; set; }
        /// <summary>
        /// 自动加载所有的数据表映射类并映射到数据库表(这个函数是重点,这里就是替代DbSet<T>属性)
        /// </summary>
        /// <param name="modelBuilder"></param>
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            //dynamically load all configuration
            System.Type configType = typeof(CategoryMap);   //any of your configuration classes here
            var typesToRegister = Assembly.GetAssembly(configType).GetTypes()
            .Where(type => !String.IsNullOrEmpty(type.Namespace))
            .Where(type => type.BaseType != null && type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
            foreach (var type in typesToRegister)
            {
                dynamic configurationInstance = Activator.CreateInstance(type);
                modelBuilder.Configurations.Add(configurationInstance);
            }
            //...or do it manually below. For example,
            //modelBuilder.Configurations.Add(new LanguageMap());

base.OnModelCreating(modelBuilder);
        }
        /// <summary>
        /// 将一个实体附加到Context上和返回已附加这个实体(if it was already attached)
        /// </summary>
        /// <typeparam name="TEntity">TEntity</typeparam>
        /// <param name="entity">Entity</param>
        /// <returns>Attached entity</returns>
        protected virtual TEntity AttachEntityToContext<TEntity>(TEntity entity) where TEntity : BaseEntity, new()
        {
            //little hack here until Entity Framework really supports stored procedures
            //otherwise, navigation properties of loaded entities are not loaded until an entity is attached to the context
            var alreadyAttached = Set<TEntity>().Local.Where(x => x.Id == entity.Id).FirstOrDefault();
            if (alreadyAttached == null)
            {
                //attach new entity
                Set<TEntity>().Attach(entity);
                return entity;
            }
            else
            {
                //entity is already loaded.
                return alreadyAttached;
            }
        }

public string CreateDatabaseScript()
        {
            return ((IObjectContextAdapter)this).ObjectContext.CreateDatabaseScript();
        }
        /// <summary>
        /// context附加实体
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <returns></returns>
        public new IDbSet<TEntity> Set<TEntity>() where TEntity : BaseEntity
        {
            return base.Set<TEntity>();
        }
        /// <summary>
        /// 执行存储过程
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="commandText"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public IList<TEntity> ExecuteStoredProcedureList<TEntity>(string commandText, params object[] parameters) where TEntity : BaseEntity, new()
        {
            //HACK: Entity Framework Code First doesn't support doesn't support output parameters
            //That's why we have to manually create command and execute it.
            //just wait until EF Code First starts support them
            //
            //More info: http://weblogs.asp.net/dwahlin/archive/2011/09/23/using-entity-framework-code-first-with-stored-procedures-that-have-output-parameters.aspx

bool hasOutputParameters = false;
            if (parameters != null)
            {
                foreach (var p in parameters)
                {
                    var outputP = p as DbParameter;
                    if (outputP == null)
                        continue;

if (outputP.Direction == ParameterDirection.InputOutput ||
                        outputP.Direction == ParameterDirection.Output)
                        hasOutputParameters = true;
                }
            }

var context = ((IObjectContextAdapter)(this)).ObjectContext;
            if (!hasOutputParameters)
            {
                //no output parameters
                var result = this.Database.SqlQuery<TEntity>(commandText, parameters).ToList();
                for (int i = 0; i < result.Count; i++)
                    result[i] = AttachEntityToContext(result[i]);

return result;

//var result = context.ExecuteStoreQuery<TEntity>(commandText, parameters).ToList();
                //foreach (var entity in result)
                //    Set<TEntity>().Attach(entity);
                //return result;
            }
            else
            {

//var connection = context.Connection;
                var connection = this.Database.Connection;
                //Don't close the connection after command execution

//open the connection for use
                if (connection.State == ConnectionState.Closed)
                    connection.Open();
                //create a command object
                using (var cmd = connection.CreateCommand())
                {
                    //command to execute
                    cmd.CommandText = commandText;
                    cmd.CommandType = CommandType.StoredProcedure;

// move parameters to command object
                    if (parameters != null)
                        foreach (var p in parameters)
                            cmd.Parameters.Add(p);

//database call
                    var reader = cmd.ExecuteReader();
                    //return reader.DataReaderToObjectList<TEntity>();
                    var result = context.Translate<TEntity>(reader).ToList();
                    for (int i = 0; i < result.Count; i++)
                        result[i] = AttachEntityToContext(result[i]);
                    //close up the reader, we're done saving results
                    reader.Close();
                    return result;
                }

}
        }
    }
}
4、在Nop.Core下的Data里建立一个接口IRepository,代码如下:
using System.Linq;

namespace Nop.Core.Data
{
    /// <summary>
    /// Repository
    /// </summary>
    public partial interface IRepository<T> where T : BaseEntity
    {
        T GetById(object id);
        void Insert(T entity);
        void Update(T entity);
        void Delete(T entity);
        IQueryable<T> Table { get; }
    }
}

5、在Nop.Core下的Data里建立一个实体EfRepository.cs,代码如下:
using System;
using System.Data.Entity;
using System.Linq;
using Nop.Core;
using Nop.Core.Data;

namespace Nop.Data
{
    /// <summary>
    /// Entity Framework repository
    /// </summary>
    public partial class EfRepository<T> : IRepository<T> where T : BaseEntity
    {       
        private readonly DbContext _context;
        private IDbSet<T> _entities;

/// <summary>
        /// Ctor
        /// </summary>
        /// <param name="context">Object context</param>
        public EfRepository(DbContext context)
        {
            this._context = context;
        }

public T GetById(object id)
        {
            return this.Entities.Find(id);
        }

public void Insert(T entity)
        {
            try
            {
                if (entity == null)
                    throw new ArgumentNullException("entity");

this.Entities.Add(entity);

this._context.SaveChanges();
            }
            catch (Exception dbEx)
            {
                var msg = string.Empty;

//foreach (var validationErrors in dbEx.EntityValidationErrors)
                //    foreach (var validationError in validationErrors.ValidationErrors)
                //        msg += string.Format("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage) + Environment.NewLine;

var fail = new Exception(msg, dbEx);
                //Debug.WriteLine(fail.Message, fail);
                throw fail;
            }
        }

public void Update(T entity)
        {
            try
            {
                if (entity == null)
                    throw new ArgumentNullException("entity");

this._context.SaveChanges();
            }
            catch (Exception dbEx)
            {
                var msg = string.Empty;

//foreach (var validationErrors in dbEx.EntityValidationErrors)
                //    foreach (var validationError in validationErrors.ValidationErrors)
                 //       msg += Environment.NewLine + string.Format("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);

var fail = new Exception(msg, dbEx);
                //Debug.WriteLine(fail.Message, fail);
                throw fail;
            }
        }

public void Delete(T entity)
        {
            try
            {
                if (entity == null)
                    throw new ArgumentNullException("entity");

this.Entities.Remove(entity);

this._context.SaveChanges();
            }
            catch (Exception dbEx)
            {
                var msg = string.Empty;

// foreach (var validationErrors in dbEx.EntityValidationErrors)
                //    foreach (var validationError in validationErrors.ValidationErrors)
                 //       msg += Environment.NewLine + string.Format("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);

var fail = new Exception(msg, dbEx);
                //Debug.WriteLine(fail.Message, fail);
                throw fail;
            }
        }

public virtual IQueryable<T> Table
        {
            get
            {
                return this.Entities;
            }
        }

private IDbSet<T> Entities
        {
            get
            {
                if (_entities == null)
                    _entities = _context.Set<T>();
                return _entities;
            }
        }
        //TODO implement IDisposable interface
    }
}

 6、在Nop.Services中建立ICategoryService和CategoryService:
ICategoryService:

using System.Collections.Generic;
using Nop.Core;
using Nop.Core.Domain.Catalog;

namespace Nop.Services.Catalog
{
    /// <summary>
    /// Category service interface
    /// </summary>
    public partial interface ICategoryService
    {

/// <summary>
        /// Gets all categories
        /// </summary>
        /// <param name="showHidden">A value indicating whether to show hidden records</param>
        /// <returns>Categories</returns>
        IList<Category> GetAllCategories(bool showHidden = false);

}
}

CategoryService:
using System.Collections.Generic;
using System.Linq;
using System.Data.Entity;
using Nop.Core.Data;
using Nop.Core.Domain.Catalog;
using Nop.Data;

namespace Nop.Services.Catalog
{
    /// <summary>
    /// Category service
    /// </summary>
    public partial class CategoryService : DbModelBuilder,ICategoryService
    {
        #region Constants
        //private const string CATEGORIES_BY_ID_KEY = "Nop.category.id-{0}";

#endregion

#region Fields

private readonly IRepository<Category> _categoryRepository;
        //private readonly DbProviderFactory _dbProviderFactory;
        #endregion

#region Ctor

public CategoryService()
        {
            var ConnectionString = "Data Source=192.168.16.2;Initial Catalog=nopCommerce;Integrated Security=False;Persist Security Info=False;User ID=sa;Password=123456;MultipleActiveResultSets=True";
            DbContext dbContext = new NopObjectContext(ConnectionString);
          
            this._categoryRepository = new EfRepository<Category>(dbContext);
           
        }

#endregion

#region Methods

/// <summary>
        /// Gets all categories
        /// </summary>
        /// <param name="showHidden">A value indicating whether to show hidden records</param>
        /// <returns>Categories</returns>
        public virtual IList<Category> GetAllCategories(bool showHidden = false)
        {
            var query = from c in _categoryRepository.Table
                        orderby c.ParentCategoryId, c.DisplayOrder
                        where (showHidden || c.Published) &&
                        !c.Deleted
                        select c;

var unsortedCategories = query.ToList();

return unsortedCategories;
        }

#endregion
    }
}

EF4.1 企业架构模式 自动映射数据表(转载)的更多相关文章

  1. SpringBoot+Mybatis 自动创建数据表(适用mysql)

    Mybatis用了快两年了,在我手上的发展史大概是这样的 第一个阶段 利用Mybatis-Generator自动生成实体类.DAO接口和Mapping映射文件.那时候觉得这个特别好用,大概的过程是这样 ...

  2. hibernate中.hbm.xml和注解方式自动生成数据表的简单实例(由新手小白编写,仅适用新手小白)

    绝逼新手小白,so 请大神指点! 如果真的错的太多,错的太离谱,错的误导了其他小伙伴,还望大神请勿喷,大神请担待,大神请高抬贵嘴......谢谢. 好了,正题 刚接触ssh,今天在搞使用.hbm.xm ...

  3. A.CTable 自动创建数据表

    1.添加依赖 <!-- A.CTable 自动创建数据表 --> <dependency> <groupId>com.gitee.sunchenbin.mybati ...

  4. springboot项目启动-自动创建数据表

    很多时候,我们部署一个项目的时候,需要创建大量的数据表.例如mysql,一般的方法就是通过source命令完成数据表的移植,如:source /root/test.sql.如果我们需要一个项目启动后, ...

  5. generator自动生成数据表

    1.先写好自己要创建的字段等: 然后将将上面的在plsql中运行,创建数据表.

  6. Hibernate不能自动建数据表解决办法

    首先自己要注意自己的MYSQL版本,然后设置对应的方言 兼容性模式 <property name="hibernate.dialect">org.hibernate.d ...

  7. Automap sqlalchemy.ext.automap 自动映射数据库表结构

    from sqlalchemy.ext.automap import automap_base from sqlalchemy.orm import Session from sqlalchemy i ...

  8. Microservice架构模式简介

    在2014年,Sam Newman,Martin Fowler在ThoughtWorks的一位同事,出版了一本新书<Building Microservices>.该书描述了如何按照Mic ...

  9. IT忍者神龟之Hibernat持久化对象-数据表映射配置回想

    1.持久化对象POJO编写规则: 1) 有空參public构造器: 2) 提供标识属性.映射数据表主键: 3) 属性提供setter和getter方法. 4) 属性使用基本数据类型的包装类型.基本类型 ...

随机推荐

  1. 适配高分辨率的图片High DPI Images for Variable Pixel Densities

    用最高的效率与性能提供最好的图片质量. 本文内容来至http://www.html5rocks.com/en/mobile/high-dpi/.是在这篇文章的翻译的基础上进行了总结和说明. 眼下面临的 ...

  2. Silverlight:《Pro Silverlight5》读书笔记 之 XAML

    XAML Properties and Events in XAML Simple Properties and Type Converters To bridge the gap between s ...

  3. linux远程连接

    1.使用putty连接 putty下载地址 http://www.putty.org/ 2.通过VNC连接 vnc_viewer 下载地址 http://www.realvnc.com/downloa ...

  4. [Gradle] Gradle 简介

    Gradle 是以 Groovy 语言为基础,面向Java应用为主.基于DSL(领域特定语言)语法的自动化构建工具. Ø gradle对多工程的构建支持很出色,工程依赖是gradle的第一公民. Ø ...

  5. 如何使用keepalived实现nginx双机热备

    1.linux安装方法:yum -y install keepalived 配置开机启动:sudo chkconfig  keepalived on 查看keepalivede运行日志:/var/lo ...

  6. java中的char占几个字节

    1:“字节”是byte,“位”是bit : 2: 1 byte = 8 bit : char 在Java中是2个字节.java采用unicode,2个字节(16位)来表示一个字符. 例子代码如下: p ...

  7. C 语言高效编程的几招——A few action of efficient C language programming

    编写高效简洁的C 语言代码,是许多软件工程师追求的目标.本文就工作中的一些体会和经验做相关的阐述,不对的地方请各位指教. 第1 招:以空间换时间 计算机程序中最大的矛盾是空间和时间的矛盾,那么,从这个 ...

  8. js版根据经纬度计算多边形面积(墨卡托投影)

    [摘要:var earthRadiusMeters = 6371000.0; var metersPerDegree = 2.0 * Math.PI * earthRadiusMeters / 360 ...

  9. Android -- Sqlite事务

    这也是通过Android Juint来实现的. 基于上一次的工程继续,上一次工程传送门:<Android–Android Juint 与 Sqlite> http://www.cnblog ...

  10. html5-video视频播放

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/ ...