Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >EF Core:使用字典属性

EF Core:使用字典属性
EN

Stack Overflow用户
提问于 2020-03-17 09:01:13
回答 5查看 17.3K关注 0票数 11

是否有方法用实体框架核心填充字典属性?

出于性能原因,我们喜欢在应用程序中搜索,而不是在数据库中搜索。由于一份清单不能很好地按比例排列,我们喜欢使用字典。

例如(简化的例子)

代码语言:javascript
运行
AI代码解释
复制
class Course
{
    public Dictionary<string, Person> Persons { get; set; }

    public int Id { get; set; }
}

class Person
{
    public string Firstname { get; set; }
    public string Lastname { get; set; }
}

我试过的东西

  • 只是天真地添加了一个字典属性。这将导致以下错误: System.InvalidOperationException:属性‘Person’无法映射,因为它的类型是'Dictionary‘,它不是受支持的原语类型或有效的实体类型。要么显式地映射这个属性,要么使用'NotMapped‘属性忽略它,或者在'OnModelCreating’中使用'EntityTypeBuilder.Ignore‘。
  • 尝试添加一个价值转换 (带有HasConversion),但是转换只在单个项上工作,而在集合上不起作用。HasMany已经提供了一个编译错误: 构建器.HasMany(c => c.Persons) //将不编译,Person不是IEnumerable .WithOne().HasForeignKey("PersonId");
  • 创建一个自定义集合类(继承自Collection并实现InsertItemSetItem等)--不幸的是,这也无法工作,因为etc将将项添加到集合中,然后首先填充属性(至少在演示中不使用我们的OwnsOne属性)--之后不会调用SetItem
  • 如果添加一个将构建字典的“计算”属性,则不会调用setter (每次使用部分值更新列表,与上面的值略有相同)。见try: 类过程{私有Dictionary _personsDict;公共列表人员{ get => _personsDict.Values.ToList();set => _personsDict = value.ToDictionary(p => p.Firstname,p => p);//从不调用} public int Id { get;set;}

当然,我可以在存储库中构建一个字典(使用存储库模式),但这很棘手,因为我可能会忘记某些部分--与运行时错误和声明性风格相比,我更喜欢编译时错误而不是命令式风格代码。

更新,以明确

  • 这不是一种代码优先的方法
  • 在EF Core中改变映射的想法,这样数据库就不会改变。-我没有故意给数据库加上标签;)
  • 如果我使用的是List而不是字典,映射就会起作用
  • 它是数据库中的1:n或n:m关系(参见HasMany - WithOne)
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2020-04-17 09:52:56

我不认为保存字典是个好主意(我甚至无法想象如何在数据库中保存字典)。正如我从您的源代码中看到的,您正在使用FirstName作为密钥。在我看来,你应该把字典改成HashSet。这样,您可以保持速度,但也保存到数据库。下面是一个示例:

代码语言:javascript
运行
AI代码解释
复制
class Course
{
    public Course() {
        this.People = new HashSet<Person>();
    }

    public ISet<Person> People { get; set; }

    public int Id { get; set; }
}

在此之后,您可以从它创建一个字典,或者继续使用哈希集。字典样本:

代码语言:javascript
运行
AI代码解释
复制
private Dictionary<string, Person> peopleDictionary = null;


public Dictionary<string, Person> PeopleDictionary {
    get {
        if (this.peopleDictionary == null) {
            this.peopleDictionary = this.People.ToDictionary(_ => _.FirstName, _ => _);
        }

        return this.peopleDictionary;
    }
}

请注意,这将意味着您的人员集将成为非同步后,您添加/删除到/从字典。为了同步更改,您应该在上下文中覆盖SaveChanges方法,如下所示:

代码语言:javascript
运行
AI代码解释
复制
public override int SaveChanges() {
    this.SyncPeople();

    return base.SaveChanges();
}

public override int SaveChanges(bool acceptAllChangesOnSuccess) {
    this.SyncPeople();

    return base.SaveChanges(acceptAllChangesOnSuccess);
}

public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default) {
    this.SyncPeople();

    return base.SaveChangesAsync(cancellationToken);
}

public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default) {
    this.SyncPeople();

    return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
}

private void SyncPeople() {
    foreach(var entry in this.ChangeTracker.Entries().Where(_ = >_.State == EntityState.Added || _.State == EntityState.Modified)) {
        if (entry.Entity is Course course) {
            course.People = course.PeopleDictionary.Values.ToHashSet();
        }
    }
}

编辑:为了有一个正在运行的代码,您需要通过NotMapped属性告诉EF不要映射字典。

代码语言:javascript
运行
AI代码解释
复制
[NotMapped]
public Dictionary<string, Person> PeopleDictionary { ... }
票数 12
EN

Stack Overflow用户

发布于 2020-04-16 08:35:05

似乎有人一直在努力解决这个问题并找到了解决办法。请参阅:使用EFCore2.1将字典存储为JSON字符串

该实体的定义如下:

代码语言:javascript
运行
AI代码解释
复制
public class PublishSource
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Required]
    public string Name { get; set; }

    [Required]
    public Dictionary<string, string> Properties { get; set; } = new Dictionary<string, string>();
}

在数据库上下文的OnModelCreating方法中,我只调用HasConversion,它执行字典的序列化和反序列化:

代码语言:javascript
运行
AI代码解释
复制
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<PublishSource>()
        .Property(b => b.Properties)
        .HasConversion(
            v => JsonConvert.SerializeObject(v),
            v => JsonConvert.DeserializeObject<Dictionary<string, string>>(v));
}

但是,我注意到的一件重要事情是,当更新实体和更改字典中的项时,EF更改跟踪不会发现字典已经更新的事实,因此您需要显式地调用DbSet<>上的Update方法来将实体设置为在更改跟踪器中修改。

票数 10
EN

Stack Overflow用户

发布于 2020-04-17 22:21:47

您可以添加一个新的属性PersonsJson来存储JSON数据。当数据从DB检索或存储到DB时,它会自动序列化或反序列化JSON数据到Persons属性中。Persons属性未映射,只映射PersonsJson

代码语言:javascript
运行
AI代码解释
复制
class Course
{
    [NotMapped]
    public Dictionary<string, Person> Persons { get; set; }

    public string PersonsJson
    {
        get => JsonConvert.SerializeObject(Persons);
        set => Persons = JsonConvert.DeserializeObject<Dictionary<string, Person>>(value);
    }

    public int Id { get; set; }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60726966

复制
相关文章
flutter中多flavors方案以及添加firebase​
有想做海外市场的同学们,可能需要用到firebase。今天我们讲讲怎么使用「FlutterFire CLI」添加 firebase以及如何设置「flavors」
用户1974410
2022/09/20
10K0
flutter中多flavors方案以及添加firebase​
REST API返回结果对象设计
基于REST API的项目返回的数据结构题都是统一的,这样方便接口对接和使用。因此,对结果对象的设计会有一定的要求:
程序新视界
2021/12/07
1K0
Yarn Rest Api使用
前言 Yarn Rest Api 返回的数据都是XML格式,需要解析XML。 任务查询 查询所有任务 http://hadoop02:8088/ws/v1/cluster/apps 字段说明 Item DataType Description id string 应用的application-id user string 提交任务的用户名 name string 应用程序的名称 queue string 应用程序所属消息队列 state string 应用程序当前状态 finalStatus str
码客说
2023/01/08
2.2K0
在 Spring Boot REST API中使用Json Web Token
在本文中,我将展示如何进行基于 Spring Boot 的 REST API进行鉴权。保护 REST API 以避免对公共 API 进行任何不必要的调用已成为一种趋势。我们将使用一些 Spring 引导功能来实现 Spring 安全,并使用 JSON WebTokens 进行授权。
用户4235284
2023/10/14
2820
在 Spring Boot REST API中使用Json Web Token
使用 %REST.API 类创建 REST 服务
创建 REST 服务的推荐方法是从 REST 服务的 OpenAPI 2.0 规范开始,并使用它来生成 REST 服务类。要使用 %REST.API 类执行此操作:
用户7741497
2022/08/05
1.6K0
使用 Burp 枚举 REST API
Burp 可以测试任何 REST API 端点,前提是您可以为该端点使用普通客户端来生成正常流量。流程是通过 Burp 代理客户端的流量,然后用正常的方式进行测试。
Khan安全团队
2022/01/14
1.3K0
使用 pyhttptest 轻松测试 REST API
现在,我们每个人都面临着 REST API,要么开发这样的服务,要么使用这样的服务。 此外,我们正处于微服务的时尚时代,我们将业务逻辑分割成独立于每个服务的小型独立服务。 这些服务大多遵循 RESTful 原则,并使用 JSON 格式进行通信,由于其简单性,JSON 格式成为最广泛使用的格式​。
叉叉敌
2020/02/18
6990
使用 pyhttptest 轻松测试 REST API
现在,我们每个人都面临着 REST API,要么开发这样的服务,要么使用这样的服务。 此外,我们正处于微服务的时尚时代,我们将业务逻辑分割成独立于每个服务的小型独立服务。 这些服务大多遵循 RESTful 原则,并使用 JSON 格式进行通信,由于其简单性,JSON 格式成为最广泛使用的格式​。
叉叉敌
2020/02/15
8220
怎么在Openresty中REST?
REST究竟指的是什么,如果原意英文缩写来看,REST(Resource Representational State Transfer ), 解释很诗意,很烂漫,但基本看不出一个所以然。
糖果
2020/09/17
2.5K0
另类玩法!使用 REST API 操作 RabbitMQ
关于 RabbitMQ 的管理,我们可以通过网页来进行,在松哥前面的文章中也和小伙伴们做了相关的介绍了:
江南一点雨
2021/12/04
9910
另类玩法!使用 REST API 操作 RabbitMQ
Elasticsearch集群配置以及REST API使用
ES安装与启动   在官网下载压缩包,解压后直接运行bin目录下的.bat文件即可。下载地址戳这里。 ES配置集群   Elasticsearch配置集群很简单,只要配置一个集群的 名称 ,ES就会自
用户1154259
2018/01/17
9880
Elasticsearch集群配置以及REST API使用
Elasticsearch使用REST API实现全文检索
通过rest api添加检索数据,阅读官方文档可以发现,elasticsearch支持动态映射,但是其中有不少问题,且听慢慢详解。 本文主要讲述三点内容: 1 Elasticsearch常用的rest api 2 Elasticsearch使用bulk命令添加索引数据 ES REST API   elasticsearch支持通过http请求响应服务,因此通过curl命令,可以发送http请求,并得到json返回内容。   常用的rest请求包括:   检查ES集群状态: curl localh
用户1154259
2018/01/17
1.3K0
Elasticsearch使用REST API实现全文检索
如何使用 Spring Boot 创建 REST API ?
Spring Boot 是一个功能强大的框架,可以轻松创建 RESTful API。在本文中,我们将逐步指导如何使用 MySQL 和 JPA 在 Spring Boot 中创建 RESTful API。我们将首先创建一个新的 Spring Boot 项目并根据我们的需求对其进行配置。
用户1418987
2023/10/26
8440
如何使用 Spring Boot 创建 REST API ?
禁止添加属性、封闭对象、冻结对象的 API
除了设置对象的属性特征,对属性进行控制,系统也提供了一些简化的 API 来进行属性控制
很酷的站长
2022/12/21
7520
禁止添加属性、封闭对象、冻结对象的 API
Rest api简介
理解和使用内容协商 我们的开发者在发送一个 REST API 请求的同时,根据应用场景,针对相同的资源,可能会期待不同的返回形式。 比如,我希望根据用户客户端语言,同一个资源的内容可以返回不同的语言。又比如,当我使用 Java 编程的时候,我希望得到 ATOM 格式的返回结果,而当我使用 JavaScript 编程的时候,我希望得到 Json 格式的返回结果。 因此,我们在设计 REST API 的时候,应该提供完备的内容协商能力。 使用 URL 参数进行内容协商 最容易想到的自然是通过 URL 参数进行控
xiangzhihong
2018/02/02
2.2K0
Rest api简介
Elasticsearch:REST API
在 Elasticsearch 中,所以的数据都是以 JSON 的格式来进行表述的。这个和其它的有些数据库,比如 Solr,它支持更多格式的数据,比如 xml, csv 等。
HLee
2021/01/26
1.3K0
Elasticsearch:REST API
Elasticsearch——Rest API中的常用用法
本篇翻译的是Elasticsearch官方文档中的一些技巧,是使用Elasticsearch必不可少的必备知识,并且适用于所有的Rest Api。 返回数据格式化 当在Rest请求后面添加?pre
用户1154259
2018/01/17
9360
Elasticsearch——Rest API中的常用用法
Windows 商店应用中使用 SharePoint REST API
前面一篇我们介绍了 Office 365 REST API 的官方工具的使用,本篇我们来看一下 SharePoint REST API 本身的描述、结构和使用方法,以及一些使用经验。 首先来看看SharePoint REST API 的概述:       REST API 服务是在 SharePoint 2013 中被引入的,官方认为 REST API 服务可以媲美于现有的 SharePoint 客户端对象模型。开发人员可以使用任何支持 REST Web 请求的技术(C#,javascript,java,o
Shao Meng
2018/04/28
4.9K0
【axios】使用json-server 搭建REST API
1.1 API 的分类 REST API: restful (Representational State Transfer (资源)表现层状态转化) (1) 发送请求进行CRUD 哪个操作由请求方式来决定 (2) 同一个请求路径可以进行多个操作 (3) 请求方式会用到GET/POST/PUT/DELETE 非REST API: restless (1) 请求方式不决定请求的CRUD 操作 (2) 一个请求路径只对应一个操作 (3) 一般只有GET/POST 1.2 使用json-server 搭建RES
玖柒的小窝
2021/10/05
2.9K0
【axios】使用json-server 搭建REST API
点击加载更多

相似问题

在firebase中使用Rest api(Casablanca c++)添加子对象时遇到问题

10

如何使用firebase rest api“注销”firebase

123

使用REST API创建Firebase

21

使用REST Api编辑子对象的属性

13

Firebase REST API

14
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文