简体   繁体   English

我将如何 go 将 EFCore DBSet 保存为 JSON?

[英]How would I go about saving an EFCore DBSet as JSON?

Hoping to get pointed in the right direction regarding some confusion with Entity Framework Core, .NET 5 if it matters.希望在与 Entity Framework Core、.NET 5 的一些混淆方面指出正确的方向(如果重要的话)。

The context for this question is an "E2E" test for lack of a better term, which is fed a scenario.这个问题的上下文是一个“E2E”测试,因为缺少一个更好的术语,这是一个场景。 (ScenarioForm, posted below) The requirement is to have a database table which tracks a given scenario and the status of it's execution, along with some unimportant metrics for the sake of this question. (ScenarioForm,发布在下面)要求有一个数据库表,用于跟踪给定场景及其执行状态,以及一些不重要的指标。

This form is fed from a service/controller and is a JSON object.此表单由服务/控制器提供,是 JSON object。 This is currently JSON because we're early days with what our "scenario" is, and want to be able to change it fairly easily.目前是 JSON,因为我们的“场景”还处于早期阶段,并且希望能够相当轻松地对其进行更改。 I got this requirement from someone higher up so please consider this requirement a constant.我从更高层的人那里得到了这个要求,所以请将此要求视为一个常数。

using System;
using Microsoft.EntityFrameworkCore;
using MyNamespace.Contracts.Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace MyNamespace.Contracts.Forms
{
    /// <summary>
    /// Defines the execution parameters of a scenario.
    /// </summary>
    [JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]
    [Keyless] // This is me trying to figure things out, probably no need to include keyless..?
    public class ScenarioForm
    {
        /// <summary>
        /// Quantity of customers created by this scenario.
        /// </summary>
        public int CustomerCount { get; set; } = 1;

        /// <summary>
        /// Id of the Organization to use in this scenario
        /// </summary>
        public Guid OrganizationId { get; set; }

        /// <summary>
        /// Type of running, whether it be from a stream or file.
        /// </summary>
        public RunnerType RunnerType { get; set; } = RunnerType.File;
    }
}

I also have an entity, which is supposed to be the representation of the status of a given scenario.我还有一个实体,它应该是给定场景状态的表示。

using System;
using System.ComponentModel.DataAnnotations.Schema;
using MyNamespace.Contracts.Forms;
using MyNamespace.Contracts.Models;

namespace MyNamespace.Data.Entities
{
    public class ScenarioStatus
    {
        public Guid Id { get; set; }
        [NotMapped] // This is leftover from me trying stuff, I imagine this should be a different relationship.
        public ScenarioForm Specification { get; set; }
        public RunnerType RunnerType { get; set; }
        public DateTime? StartedAt { get; set; }
        public DateTime? CompletedAt { get; set; }
        public DateTime? ElapsedTime { get; set; }
        public string CreatedBy { get; set; }
        public DateTime CreatedAt { get; set; }
        public string UpdatedBy { get; set; }
        public DateTime? UpdatedAt { get; set; }
    }
}

The issue that I'm running into is that I would like the ScenarioForm to just be a column in the ScenarioStatus table, as its JSON representation, instead of having an entirely seperate table for the ScenarioForm.我遇到的问题是我希望 ScenarioForm 只是 ScenarioStatus 表中的一列,作为它的 JSON 表示,而不是为 ScenarioForm 提供一个完全独立的表。

I'm also aware that it's not ideal to be defining these relationships via attributes, feel free to give direction as either attributes or using FluentAPI.我也知道通过属性来定义这些关系并不理想,请随意使用属性或使用 FluentAPI 给出方向。

Any direction appreciated please and thanks!任何方向表示赞赏,谢谢!

I chopped the code up a little bit, so if there is anything confusing let me know and I can clarify.我将代码切碎了一点,所以如果有任何令人困惑的地方,请告诉我,我可以澄清一下。

There is two way based on which database you are using.根据您使用的数据库,有两种方法。

  1. if you use Postgres easily, you can use jsonb type, and it's saved as JSON in the database.如果你容易使用 Postgres,你可以使用 jsonb 类型,它在数据库中保存为 JSON。 For more information read this有关更多信息, 请阅读此
    public class ScenarioStatus
    {
        public Guid Id { get; set; }
        [Column(TypeName = "jsonb")]
        public ScenarioForm Specification { get; set; }
        public RunnerType RunnerType { get; set; }
        public DateTime? StartedAt { get; set; }
        public DateTime? CompletedAt { get; set; }
        public DateTime? ElapsedTime { get; set; }
        public string CreatedBy { get; set; }
        public DateTime CreatedAt { get; set; }
        public string UpdatedBy { get; set; }
        public DateTime? UpdatedAt { get; set; }
    }
  1. use a converter to convert a property into JSON使用转换器将属性转换为 JSON
public class ScenarioStatusConfiguration : IEntityTypeConfiguration<ScenarioStatus>
{
    public void Configure(EntityTypeBuilder<ScenarioStatus> builder)
    {
        builder.Property(e => e.Specification).HasConversion(
            v => JsonConvert.SerializeObject(v),
            v => JsonConvert.DeserializeObject<Specification>(v)
        );
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM