Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否有使用AutoMapper';s ValueResolver是否映射EF实体的EntityKey值?_C#_Asp.net Mvc_Entity Framework_Orm_Automapper - Fatal编程技术网

C# 是否有使用AutoMapper';s ValueResolver是否映射EF实体的EntityKey值?

C# 是否有使用AutoMapper';s ValueResolver是否映射EF实体的EntityKey值?,c#,asp.net-mvc,entity-framework,orm,automapper,C#,Asp.net Mvc,Entity Framework,Orm,Automapper,我不确定这个标题是否有意义,但我现在要做的是。我使用AutoMapper将实体框架实体映射到DTO对象,反之亦然。当我尝试将DTO数据映射到EF实体时,问题就出现了。EntityKey没有属性到属性的映射。为了解决这个问题,我做了如下一些工作: Mapper.CreateMap<VideoDTO, Video>() .ForMember(dest => dest.EntityKey, opt => opt.ResolveUsi

我不确定这个标题是否有意义,但我现在要做的是。我使用AutoMapper将实体框架实体映射到DTO对象,反之亦然。当我尝试将DTO数据映射到EF实体时,问题就出现了。EntityKey没有属性到属性的映射。为了解决这个问题,我做了如下一些工作:

        Mapper.CreateMap<VideoDTO, Video>()
            .ForMember(dest => dest.EntityKey, opt =>   
opt.ResolveUsing<VideoEntityKeyResolver>());
Mapper.CreateMap()
.FormMember(dest=>dest.EntityKey,opt=>
opt.resolvesusing());
VideoEntityKeyResolver类如下所示:

public class VideoEntityKeyResolver : ValueResolver<VideoDTO, EntityKey>
{
    protected override EntityKey ResolveCore(VideoDTO source)
    {
        EntityKey key = new EntityKey("EntityFrameworkTestingEntities.Videos",
            "VideoId", source.VideoId);
        return key;
    }
}
公共类VideoEntityKeyResolver:ValueResolver
{
受保护的覆盖EntityKey ResolveCore(视频数据到源)
{
EntityKey=new EntityKey(“EntityFrameworkTestingEntities.Videos”,
“VideoId”,来源:VideoId);
返回键;
}
}
我想知道是否有一种更通用的方法来实现这一点,其中我可以有一个带有构造函数的类,该构造函数采用构造函数中的实体集名称、键属性名称和键值

我曾考虑过只向DTO对象添加一个EntityKey属性,这听起来很像跨流,因为创建DTO对象的整个目的是为了在我的应用程序的其余部分中与我的数据层紧密结合


在一个完全不相关的注释中(如果需要,我可以创建一个新问题),在使用AutoMapper时,我到底需要在哪里定义映射?目前我正在我的上下文对象(即我的EF repository对象)的构造函数中进行这项工作,但我认为这是相当昂贵的,而且并不正确,尽管它可以工作。

我还没有测试过这一点,但以下应该可以工作:

public class EntityKeyResolver<T, TProperty> : ValueResolver<T, EntityKey> where T : class
{
    private Expression<Func<T, TProperty>> _propertyExpression;
    private string _qualifiedEntitySetName;
    private string _keyName;

    public EntityKeyResolver(string qualifiedEntitySetName, string keyName, Expression<Func<T, TProperty>> propertyExpression)
    {
        _qualifiedEntitySetName = qualifiedEntitySetName;
        _keyName = keyName;
        _propertyExpression = propertyExpression;
    }

    protected override EntityKey ResolveCore(T source)
    {
        return new EntityKey(_qualifiedEntitySetName, _keyName, ExpressionHelper.GetValue(_propertyExpression));
    }
}
然后,您将按如下方式更改代码(假设VideoId是Guid):

Mapper.CreateMap()
.FormMember(dest=>dest.EntityKey,opt=>opt.ResolveUsing(新的EntityKeyResolver(“EntityFrameworkTestingEntitys.Videos”,“VideoId”,v=>v.VideoId));
可能比你想的要详细一点。通用解析器的替代方法是使用MapFrom映射实体键(它们的详细程度大致相同):

Mapper.CreateMap()
.formmember(dest=>dest.EntityKey,opt=>opt.MapFrom(src=>newentitykey(“EntityFrameworkTestingEntities.Videos”,“VideoId”,src.VideoId));

至于你的另一个问题,我习惯于创建一个静态类来初始化映射,并设置一个布尔值来判断映射是否已创建,因为每个AppDomain只需调用一次。然后,在我的存储库的构造函数中,我只调用
MapInitializer.EnsureMaps()

感谢您的详细回复。大部分都在我头上,但那更多的是我而不是你。我仍在绞尽脑汁使用lambda之类的东西。无论如何,您知道是否有自动映射方法允许您显式地将计算值指定给属性吗?如果是这种情况,我可以创建一个具有必要参数的EntityKey对象,并将该值映射到实体上的EntityKey属性。我一直在研究mapfromautomapper方法,但还没有时间深入研究它。我本来打算建议将其作为一种更简单的方法,但决定直接回答您的问题。我会在答案中加上这个。(另外,如果你认为答案符合你的需要,不要忘记投票赞成和/或接受答案)感谢你在这个问题上的超越。这真的帮助了我!我确实继续并决定只映射到EntityKey属性,这似乎已经奏效了。
internal static TProperty GetValue<T, TProperty>(T obj, Expression<Func<T, TProperty>> expression) where T : class
{
    if (obj == null)
    {
        return default(TProperty);
    }

    Func<T, TProperty> func = expression.Compile();

    return func(obj);
}
Mapper.CreateMap<VideoDTO, Video>()         
            .ForMember(dest => dest.EntityKey, opt => opt.ResolveUsing(new EntityKeyResolver<VideoDTO, Guid>("EntityFrameworkTestingEntities.Videos", "VideoId", v => v.VideoId)));
Mapper.CreateMap<VideoDTO, Video>()         
                .ForMember(dest => dest.EntityKey, opt => opt.MapFrom(src => new EntityKey("EntityFrameworkTestingEntities.Videos", "VideoId", src.VideoId)));