如何使用 SQL、LINQ ADO.NET 在 C# 中查询 JSON

作者:微信公众号:【架构师老卢】
2-18 19:21
44

概述:在当今互联互通的世界中,数据堆积得非常快。我们生成的数据比人类历史上任何时候都多,而且很多数据都以非关系格式存储,如JSON文档。JSON已经成为现代应用程序的一种无处不在的格式,用于配置文件、API、客户端和服务器之间的数据传输、数据存储等。鉴于其简单性,处理 JSON 数据绝非易事。在这篇博客中,我们将介绍 ComponentOne DataConnector for JSON,它提供了一种使用 ADO.NET 或 Entity Framework Core 连接到 JSON 数据的轻松方法。我们将讨论如何使用 C1 ADO。用于 JSON 的 NET 提供程序,用于使用 SQL 和 LI

在当今互联互通的世界中,数据堆积得非常快。我们生成的数据比人类历史上任何时候都多,而且很多数据都以非关系格式存储,如JSON文档。JSON已经成为现代应用程序的一种无处不在的格式,用于配置文件、API、客户端和服务器之间的数据传输、数据存储等。鉴于其简单性,处理 JSON 数据绝非易事。

在这篇博客中,我们将介绍 ComponentOne DataConnector for JSON,它提供了一种使用 ADO.NET 或 Entity Framework Core 连接到 JSON 数据的轻松方法。我们将讨论如何使用 C1 ADO。用于 JSON 的 NET 提供程序,用于使用 SQL 和 LINQ 查询 JSON 数据。

如何使用 SQL 查询 JSON

在此过程中,我们将遵循与使用数据库时通常使用的方法相同的方法,即:

  1. 创建连接字符串
  2. 创建连接对象
  3. 使用 SQL 查询数据

但首先,让我们从安装所需的 NuGet 包开始。

  • 打开“项目”菜单,然后选择**“管理 NuGet 包”。**
  • 浏览“C1.AdoNet的。Json' NuGet 包,然后单击“安装”。

创建连接字符串

为了与数据源连接,我们需要一个连接字符串。我们将使用 C1JsonConnectionStringBuilder 创建连接字符串。创建连接字符串需要三项:

  1. JSON DataModel:指定用于读取 JSON 数据的访问机制。指定 DataModel,您可以配置如何将对象数组建模为表。可用的不同数据模型包括 Top Level Document Model、Flattened Model 和 Relational Model。你可以在这里阅读更多关于它们的信息。
  2. Uri:指定 JSON 资源位置的 URI。您可以连接到本地文件或 HTTP 流。
  3. JSON 路径:指定要从 JSON 内容中读取的节点

下面显示了为平面数据创建连接字符串的示例:

public static class Utils  
{  
        public static string JsonDataPath => "Data\\EmployeesData.json";  
        public static C1JsonConnectionStringBuilder JsonConnectionBuilder { get; }  
  
        static Utils()  
        {  
            JsonConnectionBuilder = new C1JsonConnectionStringBuilder()  
            {  
                DataModel = "Document",  
                Uri = JsonDataPath,  
                JsonPath = "$.employees"  
            };  
        }  
}

同样,下面演示如何为关系数据创建连接字符串:

public static class Utils  
{  
        public static string JsonCustomerDataPath => "Data\\CustomersData.json";  
        public static C1JsonConnectionStringBuilder CustomerDataConnectionStringBuilder { get; }  
  
        static Utils()  
        {  
            CustomerDataConnectionStringBuilder = new C1JsonConnectionStringBuilder()  
            {  
                DataModel = "Relational",  
                Uri = JsonCustomerDataPath,  
                JsonPath = "$.customers;$.customers.Transactions"  
            };  
        }  
}

若要了解有关连接字符串格式的详细信息,请参阅此处

如何创建连接对象

现在,我们已经有了连接字符串,因此下一步是使用 C1JsonConnection 类初始化连接实例,如下所示:

private void CreateJsonConnection()  
{  
_jsonConnection = new C1JsonConnection(\_connBuilder.ConnectionString);  
}

使用 SQL 查询数据

现在连接已准备就绪,我们可以通过创建 C1JsonDataAdapter 的对象来使用 SQL 查询数据,如下所示:

C1JsonDataAdapter adapter = new C1JsonDataAdapter(_jsonConnection, sql);  
var table = new DataTable();  
adapter.Fill(table);

下面显示了一个示例平面数据以及相同的相应查询:

C1JsonDataAdapter adapter = new C1JsonDataAdapter(\_jsonConnection, “select * from employees”);  
var table = new DataTable();  
adapter.Fill(table);

对于关系数据,它可能看起来像这样:

C1JsonDataAdapter adapter = new C1JsonDataAdapter(_jsonConnection, (“Select FirstName, LastName, Amount from customers INNER JOIN Transactions ON customers._id = Transactions.customers_id where Transactions.IsSuccess=false”);
var table = new DataTable();
adapter.Fill(table);

填充 DataTable 后,数据可以显示在网格中,如下所示:

在 Entity Framework Core 中使用 LINQ 查询 JSON

在本节中,我们将讨论如何在 Entity Framework Core 中使用 LINQ 查询 JSON 数据。让我们首先安装所需的 NuGet 包,即 C1。EntityFrameworkCore.Json

安装 NuGet 包后,接下来需要设置 DbContext 并向 JSON 数据源提供连接字符串。为此,我们将使用 C1JsonConnectionStringBuilder,如下所示:

public abstract partial class DocumentContext : DbContext  
{  
        private C1JsonConnectionStringBuilder _builder;  
  
        public DocumentContext(C1JsonConnectionStringBuilder builder)  
        {  
            _builder = builder;  
            Database.AutoTransactionsEnabled = false;  
        }  
  
        public DocumentContext(DbContextOptions<DocumentContext> options)  
            : base(options)  
        {  
            Database.AutoTransactionsEnabled = false;  
        }  
  
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)  
        {  
            if (!optionsBuilder.IsConfigured)  
            {  
                optionsBuilder.UseJson(_builder.ConnectionString);  
            }  
        }  
}

如何创建 DbContext

上面的 DocumentContext 类可以用作 JSON 文档的 DbContext 的基类。可以在子类中定义模型实体。

下面显示了平面 JSON 数据源的 DbContext 示例:

public class EmployeesContext : DocumentContext  
{  
        public virtual DbSet<Employee> Employees { get; set; }  
  
        public EmployeesContext() : base(Utils.JsonConnectionBuilder) { }  
  
        protected override void OnModelCreating(ModelBuilder modelBuilder)  
        {  
            modelBuilder.Entity<Employee>(entity =>  
            {  
                entity.ToTable("employees");  
                entity.HasKey(x => x.Id);  
                entity.Property(e => e.Id).HasColumnName("Id");  
                entity.Property(e => e.FirstName).HasColumnName("FirstName");  
                entity.Property(e => e.LastName).HasColumnName("LastName");  
                entity.Property(e => e.Email).HasColumnName("Email");  
                entity.Property(e => e.DOB).HasColumnName("DOB");  
                entity.Property(e => e.Address).HasColumnName("Address");  
                entity.Property(e => e.State).HasColumnName("State");  
                entity.Property(e => e.Company).HasColumnName("Company");  
                entity.Property(e => e.Gender).HasColumnName("Gender");  
                entity.Property(e => e.JobTitle).HasColumnName("JobTitle");  
                entity.Property(e => e.Skill).HasColumnName("Skill");  
                entity.Property(e => e.Salary).HasColumnName("Salary");  
            });  
        }  
}

下面显示了关系 JSON 数据源的 DbContext 示例:

public class CustomersContext : DocumentContext  
{  
        public virtual DbSet<Customer> Customers { get; set; }  
        public virtual DbSet<Transaction> Transactions { get; set; }  
  
        public CustomersContext() : base(Utils.CustomerDataConnectionStringBuilder) { }  
  
        protected override void OnModelCreating(ModelBuilder modelBuilder)  
        {  
            modelBuilder.Entity<Transaction>(entity =>  
            {  
                entity.ToTable("Transactions");  
                entity.HasOne(e => e.Customer).WithMany(x => x.Transactions).HasForeignKey("customers_id");  
                entity.Property(e => e.Id).HasColumnName("_id");  
                entity.Property(e => e.Amount).HasColumnName("Amount");  
                entity.Property(e => e.Credited).HasColumnName("Credited");  
                entity.Property(e => e.IsSuccess).HasColumnName("IsSuccess");  
                entity.Property(e => e.Date).HasColumnName("Date");  
            });  
  
            modelBuilder.Entity<Customer>(entity =>  
            {  
                entity.ToTable("customers");  
                entity.Property(e => e.Id).HasColumnName("_id");  
                entity.Property(e => e.FirstName).HasColumnName("FirstName");  
                entity.Property(e => e.LastName).HasColumnName("LastName");  
                entity.Property(e => e.DOB).HasColumnName("DOB");  
                entity.Property(e => e.State).HasColumnName("State");  
                entity.Property(e => e.Gender).HasColumnName("Gender");  
            });  
        }  
}

使用 ComponentOne DataConnectors 基架功能,可以自动生成这些类。它是通过运行 Scaffold-DbContext 命令生成的。有关详细信息,请参阅文档中的基架主题

使用 LINQ 查询 DbContext

设置 DbContext 后,可以使用 LINQ 查询 JSON 数据源。我们可以同时使用 Query 语法或 Method 语法:

_context = new EmployeesContext();  
var employees = await _context.Employees.ToListAsync();  
  
// Employee count of companies starting with 'A'  
var employeeCountData = from employee in employees  
                        where employee.Company.StartsWith("A", StringComparison.OrdinalIgnoreCase)  
                        group employee by employee.Company into grp  
                        select new { Company = grp.Key, NumberOfEmployees = grp.Count() };  
  
// Salary growth of people working in Dynabox  
var salaryGrowthData = employees  
         .Where(x => x.Company == "Dynabox").OrderBy(x => x.DOB)  
         .Select(x => new { Age = DateTime.Now.Year - x.DOB.Year, Salary = x.Salary })  
         .Where(x => x.Age >= 18)  
         .GroupBy(x => x.Age)  
         .Select(x => new { Age = x.Key, AverageSalary = x.Select(o => o.Salary).Average() });

然后可以在网格/图表中使用数据,如下所示:

结论

在这篇博客中,我们看到了使用 C1 ADO 查询平面/关系 JSON 数据。JSON 的 NET 提供程序。虽然这篇博客展示了 ADO 的基本用法。JSON 的 NET 提供程序,该库还提供高级功能。

相关留言评论
昵称:
邮箱:
阅读排行