/// <inheritdoc />
        protected override bool IsActuallyValid(Commands.UpdatePk.UpdatePk effect)
        {
            if (effect == null)
            {
                return(false);
            }
            if (effect.EntityType != typeof(T))
            {
                return(false);
            }
            var actual = effect.UpdateValuesStringKeys;

            foreach (var kv in _expectedValues)
            {
                if (!actual.ContainsKey(kv.Key))
                {
                    return(false);
                }

                var v = actual[kv.Key];
                if (!Equals(v, kv.Value))
                {
                    return(false);
                }
            }
            return(true);
        }
        /// <inheritdoc />
        protected override string GetMessage(Commands.UpdatePk.UpdatePk command)
        {
            if (command == null)
            {
                return($"expected delete by PK for {_explanation}, but story unexpectedly ends");
            }
            if (command.EntityType != typeof(T))
            {
                return
                    ($"expected update by PK entity of type {typeof(T).Name} for {_explanation}, but got one of {command.EntityType.Name}");
            }

            if (command.KeyValues.Length != _primaryKeyObject.Length)
            {
                return($"expected update by PK for {_explanation} with key consisting of {_primaryKeyObject.Length} fields, seems that key consists of {command.KeyValues.Length} fields");
            }

            for (int i = 0; i < _primaryKeyObject.Length; i++)
            {
                if (!object.Equals(_primaryKeyObject[i], command.KeyValues[i]))
                {
                    if (_primaryKeyObject.Length == 1)
                    {
                        return($"key of updated {typeof(T).Name} must be '{_primaryKeyObject[i]}', but actually is '{command.KeyValues[i]}'");
                    }
                    else
                    {
                        return($"key field #{i} of updated {typeof(T).Name} must be '{_primaryKeyObject[i]}', but actually is '{command.KeyValues[i]}'");
                    }
                }
            }

            return($"expected update by PK for {_explanation}, but something went wrong");
        }
 /// <inheritdoc />
 protected override bool IsActuallyValid(Commands.UpdatePk.UpdatePk command)
 {
     if (command == null)
     {
         return(false);
     }
     if (command.EntityType != typeof(T))
     {
         return(false);
     }
     if (_primaryKeyObject.Length != command.KeyValues.Length)
     {
         return(false);
     }
     for (int i = 0; i < _primaryKeyObject.Length; i++)
     {
         if (!object.Equals(_primaryKeyObject[i], command.KeyValues[i]))
         {
             return(false);
         }
     }
     return(true);
 }
        /// <inheritdoc />
        protected override string GetMessage(Commands.UpdatePk.UpdatePk command)
        {
            if (command == null)
            {
                return($"expected updated entity {_explanation}, but story unexpectedly ends");
            }
            if (command.EntityType != typeof(T))
            {
                return
                    ($"expected updated entity of type {typeof(T).Name} and {_explanation}, but got one of {command.EntityType.Name}");
            }
            List <(string, object, object)> propExpectedActual = new List <(string, object, object)>();
            var actual = command.UpdateValuesStringKeys;

            foreach (var kv in _expectedValues)
            {
                if (!actual.ContainsKey(kv.Key))
                {
                    propExpectedActual.Add((kv.Key, kv.Value, null));
                }

                var v = actual[kv.Key];
                if (!Equals(v, kv.Value))
                {
                    propExpectedActual.Add((kv.Key, kv.Value, v));
                }
            }

            var propsText = string.Join(", ",
                                        propExpectedActual.Select(x => $"{x.Item1}: '{x.Item2}' expected, '{x.Item3}' got"));

            if (string.IsNullOrEmpty(_explanation))
            {
                return($"updated {typeof(T).Name} does not meet conditions: {propsText}");
            }
            return($"update '{_explanation}' does not satisfy conditions: {propsText}");
        }