Как я узнаю, что элемент был изменен в моем списке? - PullRequest
0 голосов
/ 07 ноября 2018

В настоящее время я пытаюсь создать свой собственный маленький OR-Mapper. Как и EF, у меня есть контекст и набор классов. Как пример:

public class As400Context : IDisposable
{
    public As400Set<MyClass> MyList{ get; set; }
}

В данный момент отслеживаются изменения в MyClass.

public class MyClass
{
    private HashSet<string> ChangedProperties = new HashSet<string>();
    private Dictionary<string, object> OriginalValues = new 
    Dictionary<string, object>();
    private readonly ChangeState State = new ChangeState();

    public List<string> GetChangedProperties()
    {
        return ChangedProperties.ToList();
    }

    private void Setter(string field, object value)
    {
        OriginalValues.TryGetValue(field, out object originalValue);
        if (originalValue == null)
        {
            OriginalValues.Add(field, GetType().GetField('_' + field, 
            BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this));
        }

        if (value.ToString() != originalValue.ToString())
        {
            ChangedProperties.Add(field);
        }
        else
        {
            ChangedProperties.Remove(field);
            OriginalValues.Remove(field);
        }
    }

    private string _Item;
    public string Item
    {
        get { return _Item; }
        set
        {
            Setter(nameof(Item), value);
            _Item = value;
        }
    }
}

T - это MyClass

public class As400Set<T> : List<T>
{
    public new void Add(T obj)
    {
        if (obj != null)
        {
            var state = obj.GetType().GetField("State", 
                        BindingFlags.NonPublic | BindingFlags.Instance);
            var stateValue = (ChangeState)state.GetValue(obj);
            if (stateValue != ChangeState.Modified)
                state.SetValue(obj, ChangeState.Added);

            base.Add(obj);
        }
    }

    public new void Remove(T obj)
    {
        if (obj != null)
        {
            obj.GetType().GetField("State", BindingFlags.NonPublic | 
                  BindingFlags.Instance).SetValue(obj, ChangeState.Removed);
        }
    }
}

Я не думаю, что это лучший способ. Я хотел бы иметь трекер изменений на уровне контекста. Нет проблем для добавления и удаления, но как мне это сделать для измененных элементов списка?

Например:

    var context = new As400Context();
    var myList = context.MyList.FirstOrDefault();
    myList.Item= "Test";

Извините за плохой английский, надеюсь, вы понимаете, чего я пытаюсь добиться :)

РЕДАКТИРОВАТЬ: Мне также нужно знать, какое свойство изменилось.

...