Ejemplo n.º 1
0
        public override MList <T>?Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, MList <T>?existingValue)
        {
            var existingMList = (IMListPrivate <T>?)existingValue;

            var dic = existingMList == null ? new Dictionary <PrimaryKey, MList <T> .RowIdElement>() :
                      existingMList.InnerList.Where(a => a.RowId.HasValue).ToDictionary(a => a.RowId !.Value, a => a);

            var newList = new List <MList <T> .RowIdElement>();

            var tup = EntityJsonContext.CurrentPropertyRouteAndEntity !.Value;

            var elementPr = tup.pr.Add("Item");

            var rowIdType = GetRowIdTypeFromAttribute(tup.pr);

            reader.Assert(JsonTokenType.StartArray);

            reader.Read();

            while (reader.TokenType == JsonTokenType.StartObject)
            {
                reader.Read();
                reader.Assert(JsonTokenType.PropertyName);
                if (reader.GetString() != "rowId")
                {
                    throw new JsonException($"member 'rowId' expected in {reader.CurrentState}");
                }

                reader.Read();
                var rowIdValue = reader.GetLiteralValue();

                reader.Read();
                reader.Assert(JsonTokenType.PropertyName);
                if (reader.GetString() != "element")
                {
                    throw new JsonException($"member 'element' expected in {reader.CurrentState}");
                }

                reader.Read();

                using (EntityJsonConverterFactory.SetPath($"[{newList.Count}].element"))
                {
                    if (rowIdValue != null && !rowIdValue.Equals(GraphExplorer.DummyRowId.Object))
                    {
                        var rowId = new PrimaryKey((IComparable)ReflectionTools.ChangeType(rowIdValue, rowIdType) !);

                        var oldValue = dic.TryGetS(rowId);

                        using (EntityJsonContext.SetCurrentPropertyRouteAndEntity((elementPr, tup.mod, rowId)))
                        {
                            if (oldValue == null)
                            {
                                T newValue = (T)converter.Read(ref reader, typeof(T), options) !;

                                newList.Add(new MList <T> .RowIdElement(newValue, rowId, null));
                            }
                            else
                            {
                                T newValue = converter is JsonConverterWithExisting <T> jcwe ?
                                             (T)jcwe.Read(ref reader, typeof(T), options, oldValue.Value.Element !) ! :
                                             (T)converter.Read(ref reader, typeof(T), options) !;

                                if (oldValue.Value.Element !.Equals(newValue))
                                {
                                    newList.Add(new MList <T> .RowIdElement(newValue, rowId, oldValue.Value.OldIndex));
                                }
                                else
                                {
                                    newList.Add(new MList <T> .RowIdElement(newValue));
                                }
                            }
                        }
                    }
Ejemplo n.º 2
0
    public override Lite <T>?Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, Lite <T>?existingValue)
    {
        if (reader.TokenType == JsonTokenType.Null)
        {
            return(null);
        }

        reader.Assert(JsonTokenType.StartObject);

        string?toString = null;
        string?idObj    = null;
        string?typeStr  = null;
        Entity?entity   = null;

        reader.Read();
        while (reader.TokenType == JsonTokenType.PropertyName)
        {
            var propName = reader.GetString();
            switch (propName)
            {
            case "toStr": reader.Read(); toString = reader.GetString(); break;

            case "id":
            {
                reader.Read();
                idObj =
                    reader.TokenType == JsonTokenType.Null ? null :
                    reader.TokenType == JsonTokenType.String ? reader.GetString() :
                    reader.TokenType == JsonTokenType.Number ? reader.GetInt64().ToString() :
                    reader.TokenType == JsonTokenType.True ? true.ToString() :
                    reader.TokenType == JsonTokenType.False ? false.ToString() :
                    throw new UnexpectedValueException(reader.TokenType);

                break;
            }

            case "EntityType": reader.Read(); typeStr = reader.GetString(); break;

            case "entity":
                using (EntityJsonConverterFactory.SetPath(".entity"))
                {
                    reader.Read();
                    var converter = (JsonConverterWithExisting <Entity>)options.GetConverter(typeof(Entity));
                    entity = converter.Read(ref reader, typeof(Entity), options, (Entity?)(IEntity?)existingValue?.EntityOrNull);
                }
                break;

            default: throw new JsonException("unexpected property " + propName);
            }

            reader.Read();
        }

        reader.Assert(JsonTokenType.EndObject);

        Type type = TypeLogic.GetType(typeStr !);

        PrimaryKey?idOrNull = idObj == null ? (PrimaryKey?)null : PrimaryKey.Parse(idObj, type);

        if (entity == null)
        {
            return((Lite <T>)Lite.Create(type, idOrNull !.Value, toString !));
        }

        var result = (Lite <T>)entity.ToLiteFat(toString);

        if (result.EntityType != type)
        {
            throw new InvalidOperationException("Types don't match");
        }

        if (result.IdOrNull != idOrNull)
        {
            throw new InvalidOperationException("Id's don't match");
        }

        var existing = existingValue as Lite <T>;

        if (existing.Is(result) && existing !.EntityOrNull == null && result.EntityOrNull != null)
        {
            existing.SetEntity((Entity)(IEntity)result.EntityOrNull);
            return(existing);
        }

        return(result);
    }