摘要Automapper预测

时间:2016-03-05 18:31:00

标签: c# entity-framework automapper abstraction

我使用Entity Framework 6开发web api应用程序。 我想整合并开始使用Automapper来映射我的EF entites模型。

我已经阅读了关于预测的内容并意识到有必要使用Project()。要<>如果我决定使用Automapper,以获得更好的性能。但是,我不想将我的DAL暴露给Automapper库。

有没有办法可以抽象出Automapper Project()?

提前致谢

1 个答案:

答案 0 :(得分:2)

  1. 使用“投影”方法创建界面,可以复制 原始的AutoMapper方法。
  2. 然后创建一个具体的实现。
  3. 之后,将此接口添加到存储库的构造函数中。
  4. 使用它
  5. 将接口注册到依赖注入容器。
  6. 按F5
  7. 这是一个完整的例子 (当然,您将在正确的层中拥有每个类/接口。)

    using AutoMapper;
    using AutoMapper.QueryableExtensions;
    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Linq;
    using System.Linq.Expressions;
    
    namespace ConsoleApplicationMapper
    {
        class Program
        {
            static void Main(string[] args)
            {
                Mapper.Initialize(c =>
                {
                    c.CreateMap<Customer, CustomerModel>();
                });
    
                //If you use a dependency injection container you don't have to use the constructors
                var repository = new CustomerRepository(new EntityProjector());
    
                foreach (var item in repository.GetCustomers())
                {
                    Console.WriteLine(item.Name);
                }
    
                Console.ReadLine();
            }
        }
    
        public class CustomerModel
        {
            public int CustomerId { get; set; }
            public string Name { get; set; }
        }
    
        public interface IEntityProjector
        {
            IQueryable<TDestination> ProjectTo<TDestination>(IQueryable source, params Expression<Func<TDestination, object>>[] membersToExpand);
        }
    
        public class EntityProjector : IEntityProjector
        {
            public IQueryable<TDestination> ProjectTo<TDestination>(IQueryable source, params Expression<Func<TDestination, object>>[] membersToExpand)
            {
                return source.ProjectTo(membersToExpand);
            }
        }
    
        public interface ICustomerRepository
        {
            IEnumerable<CustomerModel> GetCustomers();
        }
    
        public class CustomerRepository : ICustomerRepository
        {
            private readonly IEntityProjector projector;
            public CustomerRepository(IEntityProjector theProjector)
            {
                projector = theProjector;
            }
            public IEnumerable<CustomerModel> GetCustomers()
            {
                MyContext context = new MyContext();
    
                //Uncomment this if you want to confirm that only CustomerId,Name are selected and not LastName
                //context.Database.Log = s => Console.WriteLine(s);
    
                return context.Customers.SelectTo<CustomerModel>();
            }
        }
    
        public class Customer
        {
            public int CustomerId { get; set; }
            public string Name { get; set; }
            public string LastName { get; set; }
        }
    
    
        public class MyContext : DbContext
        {
            public DbSet<Customer> Customers { get; set; }
        }
    
        public static class MyExtentions
        {
            static IEntityProjector projector;
            static MyExtentions()
            {
                //You can get it from your dependecy injection container if you use one
                projector = new EntityProjector();
            }
            //I renamed this SelectTo instead of ProjectTo so you don't have any conflict if you use AutoMapper
            //Change it to to ProjectTo if you want
            public static IQueryable<TDestination> SelectTo<TDestination>(this IQueryable source, params Expression<Func<TDestination, object>>[] membersToExpand)
            {
                return projector.ProjectTo<TDestination>(source);
            }
        }
    }