C# 抽象自动映射
我使用实体框架6开发web api应用程序。 我想集成并开始使用Automapper来映射我的EF entites模型 我已经阅读了有关投影的内容,并意识到如果我决定使用Automapper,有必要使用Project(),以获得更好的性能。但是,我不想将我的DAL公开给Automapper库 有没有办法把Automapper项目()抽象出来 提前谢谢C# 抽象自动映射,c#,entity-framework,automapper,abstraction,C#,Entity Framework,Automapper,Abstraction,我使用实体框架6开发web api应用程序。 我想集成并开始使用Automapper来映射我的EF entites模型 我已经阅读了有关投影的内容,并意识到如果我决定使用Automapper,有必要使用Project(),以获得更好的性能。但是,我不想将我的DAL公开给Automapper库 有没有办法把Automapper项目()抽象出来 提前谢谢 使用“投影”方法创建一个界面,可以复制 原始自动映射方法 然后创建一个具体的实现 之后,将此接口添加到存储库的构造函数中 使用它 将接口注册到依赖
(当然,每个类/接口都位于正确的层中)
使用AutoMapper;
使用AutoMapper.QueryableExtensions;
使用制度;
使用System.Collections.Generic;
使用System.Data.Entity;
使用System.Linq;
使用System.Linq.Expressions;
命名空间控制台应用程序映射器
{
班级计划
{
静态void Main(字符串[]参数)
{
初始化映射器(c=>
{
c、 CreateMap();
});
//如果使用依赖项注入容器,则不必使用构造函数
var repository=new CustomerRepository(new EntityProjector());
foreach(repository.GetCustomers()中的var项)
{
Console.WriteLine(项目名称);
}
Console.ReadLine();
}
}
公共类CustomerModel
{
public int CustomerId{get;set;}
公共字符串名称{get;set;}
}
公共接口IEntityProjector
{
IQueryable ProjectTo(IQueryable源,参数表达式[]membersToExpand);
}
公共类EntityProjector:IEntityProjector
{
公共IQueryable项目到(IQueryable源,参数表达式[]成员扩展)
{
返回source.ProjectTo(membersToExpand);
}
}
公共接口ICCustomerRepository
{
IEnumerable GetCustomers();
}
公共类CustomerRepository:ICCustomerRepository
{
私人只读IEntityProjector投影仪;
公共客户存储库(客户项目或项目)
{
投影仪=投影仪;
}
公共IEnumerable GetCustomers()
{
MyContext上下文=新的MyContext();
//如果要确认只选择CustomerId、Name而不选择LastName,请取消对此的注释
//context.Database.Log=s=>Console.WriteLine;
返回context.Customers.SelectTo();
}
}
公共类客户
{
public int CustomerId{get;set;}
公共字符串名称{get;set;}
公共字符串LastName{get;set;}
}
公共类MyContext:DbContext
{
公共数据库集客户{get;set;}
}
公共静态类MyExtensions
{
静态投影投影仪;
静态MyExtensions()
{
//如果您使用dependecy注射容器,则可以从容器中获取
投影仪=新的EntityProjector();
}
//我将此SelectTo重命名为而不是ProjectTo,这样在使用AutoMapper时就不会有任何冲突
//如果需要,请将其更改为ProjectTo
公共静态IQueryable SelectTo(此IQueryable源,参数表达式[]membersToExpand)
{
将投影仪返回到(源);
}
}
}
您是否愿意完整地完成您的示例,包括您在最后提到的可能的扩展方法?我想我自己不知道如何实施它。不管怎样,非常感谢much@S.Peter更新。如果您有任何问题,请告诉我。现在您可以删除存储库的构造函数和私有字段。我只是将其保留在那里,以防您不想使用扩展方法扩展类必须是静态的,对吗?我可以注入到静态类中吗?以前从未尝试过。不幸的是,您需要一个静态类。这很棘手。请参阅相关问题,我强烈建议不要使用这些层规则。间接只是引入了复杂性,没有多少好处。
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);
}
}
}