【问题标题】:How to use JsonObject of Pomelo.EntityFramework如何使用 Pomelo.EntityFramework 的 JsonObject
【发布时间】:2020-09-29 17:19:52
【问题描述】:

我想将字符串列表作为 json 存储到 mysql 表中。我在 pomelo entityframework 中看到了对此的支持。我关注了这个https://libraries.io/github/tuanbs/Pomelo.EntityFrameworkCore.MySql

这是我的实体

public class Project
{
   public int Id {get;set;}

   public string Title {get;set;}

   public JsonObject<List<string>> Tags {get;set;}
}

但是当 _context.Database.EnsureDeleted(); 被调用时,它会给出以下错误

实体类型“项目”上的导航属性“标签”不是虚拟的。 UseLazyLoadingProxies 要求所有实体类型都是公共的, 未密封,具有虚拟导航属性,并具有公共或 受保护的构造函数。

但是我必须添加虚拟关键字的不是导航属性,而是一列。不知道我在这里错过了什么。

【问题讨论】:

    标签: mysql .net-core entity-framework-core ef-code-first pomelo-entityframeworkcore-mysql


    【解决方案1】:

    查看以下示例代码,该代码取自我们 GitHub 存储库上的 my post,并且可以正常运行:

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.Extensions.Logging;
    using Pomelo.EntityFrameworkCore.MySql.Storage;
    
    namespace IssueConsoleTemplate
    {
        public class IceCream
        {
            public int IceCreamId { get; set; }
            public string Name { get; set; }
            public JsonObject<Energy> Energy { get; set; }
            public JsonObject<List<string>> Comments { get; set; }
        }
    
        public class Energy
        {
            public double Kilojoules { get; set; }
            public double Kilocalories { get; set; }
        }
    
        public class Context : DbContext
        {
            public virtual DbSet<IceCream> IceCreams { get; set; }
    
            protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
            {
                optionsBuilder
                    .UseMySql("server=127.0.0.1;port=3306;user=root;password=;database=So62301095",
                        b => b.ServerVersion(new ServerVersion("8.0.20-mysql")))
                    .UseLoggerFactory(LoggerFactory.Create(b => b
                        .AddConsole()
                        .AddFilter(level => level >= LogLevel.Information)))
                    .EnableSensitiveDataLogging()
                    .EnableDetailedErrors();
            }
        }
    
        internal class Program
        {
            private static void Main()
            {
                using (var context = new Context())
                {
                    context.Database.EnsureDeleted();
                    context.Database.EnsureCreated();
    
                    context.IceCreams.AddRange(
                        new IceCream
                        {
                            Name = "Vanilla",
                            Energy = new Energy
                            {
                                Kilojoules = 866.0,
                                Kilocalories = 207.0
                            },
                            Comments = new List<string>
                            {
                                "First!",
                                "Delicious!"
                            }
                        },
                        new IceCream
                        {
                            Name = "Chocolate",
                            Energy = new Energy
                            {
                                Kilojoules = 904.0,
                                Kilocalories = 216.0
                            },
                            Comments = new List<string>
                            {
                                "My husband likes this one a lot."
                            }
                        });
    
                    context.SaveChanges();
                }
    
                using (var context = new Context())
                {
                    var result = context.IceCreams
                        .OrderBy(e => e.IceCreamId)
                        .ToList();
    
                    Debug.Assert(result.Count == 2);
    
                    Debug.Assert(result[0].Name == "Vanilla");
                    Debug.Assert(result[0].Energy.Object.Kilojoules == 866.0);
                    Debug.Assert(result[0].Comments.Object.Count == 2);
                    Debug.Assert(result[0].Comments.Object[0] == "First!");
                }
            }
        }
    }
    

    它会生成以下 SQL:

    info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
          Entity Framework Core 3.1.3 initialized 'Context' using provider 'Pomelo.EntityFrameworkCore.MySql' with options: ServerVersion 8.0.20 MySql SensitiveDataLoggingEnabled DetailedErrorsEnabled
    
    info: Microsoft.EntityFrameworkCore.Database.Command[20101]
          Executed DbCommand (81ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
    
          DROP DATABASE `So62301095`;
    
    info: Microsoft.EntityFrameworkCore.Database.Command[20101]
          Executed DbCommand (12ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
    
          CREATE DATABASE `So62301095`;
    
    info: Microsoft.EntityFrameworkCore.Database.Command[20101]
          Executed DbCommand (66ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
    
          CREATE TABLE `IceCreams` (
              `IceCreamId` int NOT NULL AUTO_INCREMENT,
              `Name` longtext CHARACTER SET utf8mb4 NULL,
              `Energy` json NULL,
              `Comments` json NULL,
              CONSTRAINT `PK_IceCreams` PRIMARY KEY (`IceCreamId`)
          );
    
    info: Microsoft.EntityFrameworkCore.Database.Command[20101]
          Executed DbCommand (15ms) [Parameters=[@p0='["First!","Delicious!"]', @p1='{"Kilojoules":866.0,"Kilocalories":207.0}', @p2='Vanilla' (Size = 4000)], CommandType='Text', CommandTimeout='30']
    
          INSERT INTO `IceCreams` (`Comments`, `Energy`, `Name`)
          VALUES (@p0, @p1, @p2);
          SELECT `IceCreamId`
          FROM `IceCreams`
          WHERE ROW_COUNT() = 1 AND `IceCreamId` = LAST_INSERT_ID();
    
    info: Microsoft.EntityFrameworkCore.Database.Command[20101]
          Executed DbCommand (1ms) [Parameters=[@p0='["My husband likes this one a lot."]', @p1='{"Kilojoules":904.0,"Kilocalories":216.0}', @p2='Chocolate' (Size = 4000)], CommandType='Text', CommandTimeout='30']
    
          INSERT INTO `IceCreams` (`Comments`, `Energy`, `Name`)
          VALUES (@p0, @p1, @p2);
          SELECT `IceCreamId`
          FROM `IceCreams`
          WHERE ROW_COUNT() = 1 AND `IceCreamId` = LAST_INSERT_ID();
    
    info: Microsoft.EntityFrameworkCore.Database.Command[20101]
          Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
    
          SELECT `i`.`IceCreamId`, `i`.`Comments`, `i`.`Energy`, `i`.`Name`
          FROM `IceCreams` AS `i`
          ORDER BY `i`.`IceCreamId`
    

    仔细查看 IceCream.Comments 属性,这正是您想要的。

    在下面的同一个 GitHub 问题上,您可以找到我的 another post,其中包含一个更复杂的示例。

    此外,我们接下来将实现对 Pomelo 的完整 JSON 支持(可能在一周内)。

    【讨论】:

    • 请注意,JsonObject&lt;T&gt; 现已弃用,有关详细信息,请参阅 this answer
    猜你喜欢
    • 2014-12-13
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 2021-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多