使用AutoMapper与EF Code First共享,同时共享映射

时间:2017-01-18 14:09:19

标签: c# entity-framework automapper

鉴于以下内容:

public class Foo
{
    public Int32 Foo_PK { get; set; }
    public String SomeProperty { get; set; }
}
public class Bar
{
    public Int32 Bar_PK { get; set; }
    public Int32 Foo_FK { get; set; }
    public String SomeOtherProperty { get; set; }
}
public class JoinResult<TEntity, TJoiningEntity>
{
    public TEntity From { get; private set; }
    public TEntity To { get; private set; }
    public JoinResult(TEntity from, TEntity to)
    {
        this.From = from;
        this.To = to;
    }
}
public interface IFooResult
{
    public String SomeProperty { get; set; }
}
public interface IBarResult : IFooResult
{
    public String SomeOtherProperty { get; set; }
}
public class FooResultDTO : IFooResult, IBarResult
{
    public String SomeProperty { get; set; }
    public String SomeOtherProperty { get; set; }
}

这背后的想法是我们使用其他相关记录来分配foo和foo的一些方法,例如:如果有4个条形,那么表格中有4行,附加字段。

public class FooDispensary
{
    public IQueryable<T> Dispense<T>()
    where T: IFooResult
    {
        using (var repository = new Repository())
        {
            // TODO: Handle mapping for Foo -> FooResult

            // Project to
            return repository.Foos.ProjectTo<FooResultDTO>();
        }
    } 
    public IQueryable<T> DispenseWithBars<T>()
    where T : IFooResult, IBarResult
    {
        using (var repository = new Repository())
        {
            // TODO: Handle mapping for JoinResult.From (same as Foo -> FooResult) as well as to JoinResult.To

            // Project to
            return repository.Foos.Join((f) => f.Foo_PK,
                                        (b) => b.Foo_FK,
                                        (f, b) => new JoinResult<Foo, Bar>(f, b))
                                   .ProjectTo<FooResultDTO>();
        }
    } 
}

但是,我最好只指定一次基本映射(Foo - &gt; IFooResult),然后在我们需要连接到子表的方法中重复使用它。

有很多原因需要这样做,这是我的项目特有的,但不需要进入它们,我只是想知道这是否可能,因为我到目前为止一直在努力解决这个问题?

由于

1 个答案:

答案 0 :(得分:0)

FooFooResult之间创建地图。因为属性SomeProperty在源和目标中的名称相同,Automapper将能够隐式地找出映射。

// TODO: Handle mapping for Foo -> FooResult
AutoMapper.Mapper.CreateMap<Foo, FooResult>();

然后在JoinResult<Foo, Bar>FooResultDTO

之间创建地图
// TODO: Handle mapping for JoinResult.From (same as Foo -> FooResult) as well as to JoinResult.To
AutoMapper.Mapper.CreateMap<JoinResult<Foo, Bar>, FooResultDTO>()
     .ForMember(r => r.SomeProperty, opt => opt.MapFrom(f => f.From.SomeProperty)
     .ForMember(r => r.SomeOtherProperty, opt => opt.MapFrom(f => f.To.SomeOtherProperty)
  

但是,我最好只指定一次基本映射(Foo - &gt; IFooResult),然后在我们需要连接到子表的方法中重复使用它。

您未在示例中的任何位置重复使用FooIFooResult之间的映射。您的第二个功能需要在JoinResult<Foo, Bar>FooResultDTO之间进行映射,如上所示。如果您需要重用映射,我建议您考虑使用AutoMapper Profile并管理可在您的函数之间共享的单例AutoMapper实例:https://github.com/AutoMapper/AutoMapper/wiki/Configuration