Основа для объединения хозяйствующих субъектов
Есть ли рамки, которые могут сделать следующее:
var source = new Entity()
{
StringProp = null,
IntProp = 100,
};
var target = new Entity()
{
StringProp = "stringValue", // Property value should remain the same if source value is null
IntProp = 222
};
var mergedEntity = MergeFramework.Merge(source, target); // Here is what I am looking for
Assert.AreEqual(100, mergedEntity.IntField);
Assert.AreEqual("stringValue", mergedEntity.StringField);
Ниже рабочий процесс, где мне это нужно:
Приложение получает экземпляр объекта. Некоторые свойства экземпляра являются нулевыми. (исходный экземпляр)
Приложение извлекает из базы данных сущность с той же идентичностью, что и в источнике. (целевой экземпляр)
Объединяет две сущности и сохраняет объединенные в базу данных.
Основная проблема заключается в том, что в моем проекте около 600 объектов, поэтому я не хочу писать логику слияния для каждого объекта вручную. По сути, я ищу что-то гибкое, например, AutoMapper или ValueInjecter, которое удовлетворяет следующим требованиям:
Предоставить возможность указать условия слияния типов. Например: если source.IntProp == int.MinInt -> не объединять свойство
Предоставить возможность указать специфические условия недвижимости. Как в AutoMapper:
Mapper.CreateMap (). ForMember (dest => dest.EventDate, opt => opt.MapFrom (src => src.EventDate.Date));
2 ответа
Ну вот:
using System;
using NUnit.Framework;
using Omu.ValueInjecter;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
var source = new Entity()
{
StringProp = null,
IntProp = 100,
};
var target = new Entity()
{
StringProp = "stringValue", // Property value should remain the same if source value is null
IntProp = 222
};
var mergedEntity = (Entity) target.InjectFrom<Merge>(source);
Assert.AreEqual(100, mergedEntity.IntProp);
Assert.AreEqual("stringValue", mergedEntity.StringProp);
Console.WriteLine("ok");
}
}
public class Merge : ConventionInjection
{
protected override bool Match(ConventionInfo c)
{
return c.SourceProp.Name == c.TargetProp.Name
&& c.SourceProp.Value != null;
}
}
public class Entity
{
public string StringProp { get; set; }
public int IntProp { get; set; }
}
}
Чтобы обновить текущий ответ, ConventionInjection
был объявлен устаревшим Теперь вы можете использовать LoopInjection
при создании пользовательских инъекций.
Пример обновленного Merge
Инъекционный класс:
public class Merge : LoopInjection
{
protected override bool MatchTypes(Type source, Type target)
{
return source.Name == target.Name;
}
protected override void SetValue(object source, object target, PropertyInfo sp, PropertyInfo tp)
{
if (sp.GetValue(source) == null) return;
base.SetValue(source, target, sp, tp);
}
}