gpt4 book ai didi

c# - 是否有使用 AutoMapper 的 ValueResolver 映射 EF 实体的 EntityKey 值的通用方法?

转载 作者:太空狗 更新时间:2023-10-29 21:25:37 25 4
gpt4 key购买 nike

不确定标题是否有意义,但这就是我正在做的。我正在使用 AutoMapper 将我的 Entity Framework 实体映射到我的 DTO 对象,反之亦然。当我尝试将 DTO 数据映射到 EF 实体时,问题就出现了。 EntityKey 没有属性到属性的映射。要解决此问题,我会执行以下操作:

        Mapper.CreateMap<VideoDTO, Video>()
.ForMember(dest => dest.EntityKey, opt =>
opt.ResolveUsing<VideoEntityKeyResolver>());

VideoEntityKeyResolver 类如下所示:

public class VideoEntityKeyResolver : ValueResolver<VideoDTO, EntityKey>
{
protected override EntityKey ResolveCore(VideoDTO source)
{
EntityKey key = new EntityKey("EntityFrameworkTestingEntities.Videos",
"VideoId", source.VideoId);
return key;
}
}

我想知道是否有一种更通用的方法可以做到这一点,我可以让 1 个类的构造函数在构造函数中获取实体集名称、键属性名称和键值。

我考虑过只向我的 DTO 对象添加一个 EntityKey 属性,这听起来很像跨越流,因为创建 DTO 对象的全部目的是在我的应用程序的其余部分中切断与我的数据层的联系。

关于一个完全不相关的说明(如果需要,我可以创建一个新问题),使用 AutoMapper 时我到底需要在哪里定义我的映射?目前我正在我的上下文对象(这是我的 EF 存储库对象)的构造函数中执行此操作,但我认为这相当昂贵并且不正确,但它有效。

最佳答案

我还没有进行过测试,但以下应该可行:

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));
}
}

ExpressionHelper 是一个静态类,我用它来帮助计算各种情况下的表达式。 GetValue 方法如下所示:

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);
}

然后您可以按如下方式更改您的代码(假设 VideoId 是一个 Guid):

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

可能比您想要的更冗长。通用解析器的替代方法是使用 MapFrom 映射实体键(它们同样冗长):

Mapper.CreateMap<VideoDTO, Video>()         
.ForMember(dest => dest.EntityKey, opt => opt.MapFrom(src => new EntityKey("EntityFrameworkTestingEntities.Videos", "VideoId", src.VideoId)));

关于您的其他问题,我已经习惯于创建一个静态类来初始化我的映射并设置一个 bool 值来确定是否已创建映射,因为您只需要为每个 AppDomain 调用一次。然后,在我的存储库的构造函数中,我只需调用 MapInitializer.EnsureMaps();

关于c# - 是否有使用 AutoMapper 的 ValueResolver 映射 EF 实体的 EntityKey 值的通用方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2147554/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com