zoukankan      html  css  js  c++  java
  • EF4.1 企业架构模式 自动映射数据表(转载)

    在讲解之前,先来看看解决方案的架构:
    EF4.1 企业架构模式 自动映射数据表 - qiuguangchun - sandea的个人主页
    1、在Nop.Core下的Domain里建立一个实体Category;
    2、在Nop.Data下的MappingCatatog下建立一个数据表映射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
        }
    }
  • 相关阅读:
    (Java实现) 洛谷 P1106 删数问题
    (Java实现) 洛谷 P1603 斯诺登的密码
    (Java实现) 洛谷 P1036 选数
    (Java实现) 洛谷 P1012 拼数
    (Java实现) 洛谷 P1028 数的计算
    (Java实现) 洛谷 P1553 数字反转(升级版)
    (Java实现) 洛谷 P1051 谁拿了最多奖学金
    (Java实现) 洛谷 P1051 谁拿了最多奖学金
    (Java实现) 洛谷 P1106 删数问题
    目测ZIP的压缩率
  • 原文地址:https://www.cnblogs.com/sandea/p/3289926.html
Copyright © 2011-2022 走看看