Рамки для слияния хозяйствующих субъектов

Есть ли фреймворк, который может делать следующее:

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

Ниже представлен рабочий процесс там, где он мне нужен:

  1. Приложение получает экземпляр сущности. Некоторые свойства экземпляра равны нулю. (исходный экземпляр)

  2. Приложение извлекает из базы данных объект с тем же идентификатором, что и в источнике. (целевой экземпляр)

  3. Объединяет две сущности и сохраняет объединенные в базу данных.

Основная проблема в том, что в моем проекте около 600 сущностей, поэтому я не хочу писать логику слияния для каждой сущности вручную. По сути, я ищу что-то гибкое, например AutoMapper или ValueInjecter, которое удовлетворяет следующим требованиям:

  • Предоставить возможность указать условия слияния типов. Например: если source.IntProp == int.MinInt -> не объединять свойство

  • Предоставьте возможность указать конкретные условия собственности. Как в AutoMapper:

    Mapper.CreateMap (). ForMember (dest => dest.EventDate, opt => opt.MapFrom (src => src.EventDate.Date));


person k0stya    schedule 14.04.2012    source источник


Ответы (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; }
    }

}
person Omu    schedule 15.04.2012

Чтобы обновить текущий ответ, ConventionInjection устарел. Теперь вы можете использовать LoopInjection при создании пользовательских инъекций.

Пример обновленного класса Merge Injection:

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

}
person Haukur Kristinsson    schedule 26.10.2016
comment
Теперь я использую ExpressMapper вместо ValueInjector. :-) - person Haukur Kristinsson; 06.01.2017