3

需要自动映射器将域类型的属性从上下文映射回现有实体(基本上只是更新已更改的字段)。我需要它来忽略导航属性,只映射标量属性。

如果我说 ForMember(o => o.MyNavProperty, opt => opt.Ignore) 我可以让它工作,但我宁愿为我的所有映射提供一个通用方法来告诉它只映射标量而不是导航属性.

试图遵循毛里西奥的解决方案:

ASP.net MVC - 我应该使用从 ViewModel 到实体框架实体的 AutoMapper 吗?

但我无法让它成功忽略我的导航属性。

这是我的更新版本:

      private static void CreateMapForEF<TDto, TEntity>()
      {
         Mapper.CreateMap<TDto, TEntity>()
    .ForAllMembers(o => o.Condition(ctx =>
                                       {

                                          var members = ctx.Parent.SourceType.GetMember(ctx.MemberName); // get the MemberInfo that we are mapping

                                          if (!members.Any())
                                             return false;

                                          if (members.First().GetCustomAttributes(
                                                typeof (EdmRelationshipNavigationPropertyAttribute), false).Any())
                                             return false;

                                          return members.First().GetCustomAttributes(typeof(EdmScalarPropertyAttribute), false).Any(); // determine if the Member has the EdmScalar attribute set

                                       }));
      }
4

2 回答 2

5

我最近正在研究它。
您可以使用以下解决方案:

定义导航属性的属性:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class NavigationPropertyAttribute : Attribute
{
} 

使用上述属性标记视图模型中的所有导航属性。

public class TagModel
{
    public int Id { get; set; }

    [Required]
    public string Name { get; set; }

    public string Description { get; set; }

    [Display(Name = "Image")]
    public string ImagePath { get; set; }

    [NavigationProperty]
    public List<ContentModel> Contents { get; set; }
}

为 AutoMapper 编写扩展方法以忽略所有具有属性的 NavigationProperty属性。

public static IMappingExpression<TSource, TDestination> IgnoreNavigationProperties<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
{
    var sourceType = typeof(TSource);

    foreach (PropertyInfo property in sourceType.GetProperties())
    {
        var isNavProp = property.GetCustomAttributes(typeof(NavigationPropertyAttribute), false).Count() == 1;
        if (isNavProp)
                expression.ForMember(property.Name, opt => opt.Ignore());
    }
    return expression;
}

最后,您可以按如下方式使用它:

Mapper.CreateMap<TagModel, Tag>()
        .ForMember(m => m.Id, opt => opt.Condition(m => m.Id > 0))
        .IgnoreNavigationProperties();
于 2013-04-26T22:35:53.457 回答
1

我通过向实体添加接口并映射到/从接口来使用显式方法。因此,我没有排除我要明确包含的内容。通过声明部分类来添加接口。

该接口对我来说是免费的,因为我使用该接口进行解耦、测试存根、模拟等。

也许只有我一个人,但我不喜欢在 AutoMapper 配置中看到任何忽略。不能证明这一点,但对我来说感觉不对。

于 2012-09-30T05:36:03.310 回答