标签档案:json

使用JSON数据和EF Core种子数据库

我非常习惯使用标准代码(c#和EF api)来让EF帮助我建立数据库。你知道的,实例化一个对象,填充的字段,可能向相关列表添加对象。然后将整个工具包添加到DbContext并调用SaveChanges。

我向Geoffrey Grossenbach展示了一些EF Core代码,当时我们正在讨论如何在我开始认真学习一门更严肃的课程之前,在EF Core上为Pluralsight做一个接一个的演示。Geoffrey查看了所有用于构建我的对象来创建数据库的代码,然后说:“哇,代码真多。你就不能用JSON之类的吗?”(注意:我已经厌倦了在wordpress中格式化这些代码,但你明白我的意思吧?)

私有静态列表BuildWeatherEvents() {var events = new List {WeatherEvent.Create(date . time . now,WeatherType.Sun,新列表
         
          {new []{"Julie","Oh so sunny!"}}),WeatherType.Rain WeatherEvent.Create (DateTime.Now.AddDays (2)),WeatherType.Sun WeatherEvent.Create (DateTime.Now.AddDays (3),新列表
          
           {“朱莉”,“哦,可爱的夏日阳光!”太糟糕了,我在电脑上。new[]{“佛蒙特州的每个人”,“万岁,我们去玩吧!”新[]{“桑普森”,“我想去游泳,请!”},}),WeatherType.Cloudy WeatherEvent.Create (DateTime.Now.AddDays (4)),WeatherType.Rain WeatherEvent.Create (DateTime.Now.AddDays (5)),WeatherEvent.Create (DateTime.Now.AddDays (6)、WeatherType.Sun)};var lastEvent = WeatherEvent.Create(date . now . adddays (-1)),WeatherType.Snow,新列表
           
            {new[] {"Julie",“雪?7月吗?好吧,这对VT来说也太荒谬了!”}});lastevent.reactions.firstOrDefault().comments.add(new comment text=“get over it,朱莉!”});events.Add (lastEvent);返回事件;}
           
          
         

哦,那该多漂亮啊。下面是我用EF Core做的,但是你也可以用同样的概念来做EF6。

我的域名是WeatherEvent,它是我EFCore demo中的域名https://github.com/julielerman/EFCore-ASPNetCore-WebAPI-RTM,(我还没有更新以演示如何使用JSON数据)。

这是我存储在一个名为weatherdatasee .json文件中的json。

[{"date": "2016-07-27T00:00:00",“时间”:“22:09:13.8216230”,“类型”:5" response ": [{"name": "Julie",引文:“哦,阳光明媚!”“评论”:[]},“mostCommonWord”:零},{“日期”:“2016 - 07 - 25 t00:00:00”,“时间”:“22:09:13.8237230”,“类型”:1、“反应”:[],“mostCommonWord”:零},{“日期”:“2016 - 07 - 24 t00:00:00”,“时间”:“22:09:13.8238740”,“类型”:5" response ": [{"name": "Julie",引文:“哦,可爱的夏日阳光!”太糟糕了,我在电脑上。“评论”:[]},{"name": "Everyone in vermont",引文:“万岁,我们去玩吧!”“评论”:[]},{" name ":“山”,引文:“我想去游泳,请!”“评论”:[]},“mostCommonWord”:零},{“日期”:“2016 - 07 - 23 t00:00:00”,“时间”:“22:09:13.8239130”,“类型”:6,“反应”:[],“mostCommonWord”:零},{“日期”:“2016 - 07 - 22 t00:00:00”,“时间”:“22:09:13.8239210”,“类型”:1、“反应”:[],“mostCommonWord”:零},{“日期”:“2016 - 07 - 21 t00:00:00”,“时间”:“22:09:13.8239290”,“类型”:5“反应”:[],“mostCommonWord”:零},{“日期”:“2016 - 07 - 26 t00:00:00”,“时间”:“22:09:13.8239360”,“类型”:2" response ": [{"name": "Julie",“引用”:“雪吗?7月吗?好吧,这对VT来说也是荒谬的!”"comments": [{"text": "Get over it,朱莉!”}],“最常用词”:null}]

这不仅仅是数据,而是有3个层次关系的层次数据。用json表示它要简单得多、漂亮得多可读的而不是用c#构建所有这些,创建对象,等。

现在当然是魔法的时候了JSON.NET这使得将这些数据导入EF变得简单而甜蜜成为可能。

这是我使用EF从JSON中播种数据库的完整代码。

我在configure方法内的ASP.NET核心Web API中从startup.cs调用它。这里我只是用system.io.file.readalltext读取文件,然后将该文本传递到seedit方法中。还要注意ConfigureServices,我在其中设置了DbContext及其所需的连接字符串。

注意:这篇文章中的代码有一些变动肖恩Wildermuth我和戴夫·福勒一起在推特上学习,aspnet团队的核心领导者之一。我根据Shawn的一个很好的建议,修改了我的原始代码来简化它,但是Dave指出了其中的一些范围问题。现在样本回到了原始版本,其中seedit方法负责创建一个新的ServiceScope并实例化上下文。

public void ConfigureServices(IServiceCollection services) {services. adddbcontext
         
          (options=>options.usenpgsql(configuration[“data:postgreconnection:connectionString”]);services.AddMvc ();} public void Configure(IApplicationBuilder app,IHostingEnvironment env,{loggerFactory. addconsole (Configuration.GetSection("Logging"));loggerFactory.AddDebug ();app.UseMvc ();var dataText = System.IO.File.ReadAllText (@“weatherdataseed.json”);Seeder.Seedit (dataText app.ApplicationServices);
          }
         

这是Seedit方法,它使用json.net将json反序列化为weatherEvent对象列表。契约序列化器是为了克服WeatherEvent类中的私有setter。我从Daniel Wertheim的github repo报道。然后,我使用ASP.NET核心服务提供程序获取在启动时设置的服务,该服务将实例化weatherContext以及在启动中指定的连接字符串。

使用系统;使用来;使用System.Collections.Generic;使用Microsoft.Extensions.DependencyInjection;使用EFCoreWebAPI;使用Newtonsoft.Json;使用JsonNet.PrivateSettersContractResolvers;public static void Seedit(string jsonData,{ContractResolver = new PrivateSetterContractResolver()};列表
         
          事件= JsonConvert.DeserializeObject
          
           > (jsonData设置);使用(var serviceScope = serviceProvider .GetRequiredService
           
            ().CreateScope() {var context = serviceScope .ServiceProvider.GetService
            
             ();if (!context.WeatherEvents.Any()) {context.AddRange(events);context.SaveChanges ();}}}}
            
           
          
         

实例化上下文之后,我用它来检查数据库中是否有任何天气事件,所以我没有重新播种。(这是我在我的演示期间想要播种的逻辑,因此您可能对播种有不同的规则。)现在,我在WeatherEvent对象列表中调用Context.AddRange传递。我可以直接使用DbSet或上下文来调用AddRange。最后,SaveChanges。

关键是,无论您使用的是EFCore还是EF6(所以服务的使用是特定于我的应用程序是一个ASPNET Core api这一事实的),只是读取json文件,反序列化数据并将其添加到上下文中。这比强制创建所有数据要简单得多。

它可能并不总是答案,这取决于您的数据的形状,但对于这个特定的模型和我需要的种子数据来说,它是完美的。