Я не зашел так далеко, чтобы проверить это, но должно работать следующее:
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)));
Что касается вашего другого вопроса, у меня появилась привычка создавать статический класс, который инициализирует мои карты и устанавливает логическое значение относительно того, созданы ли сопоставления, так как вам нужно вызывать его только один раз для AppDomain. Затем в конструкторе моего хранилища я просто вызываю MapInitializer.EnsureMaps();