EF Core 索引器属性(Indexer property)场景及应用

news/2024/9/20 23:29:33/文章来源:https://www.cnblogs.com/goodluckily/p/18354495

EF Core 索引器属性(Indexer property)场景及应用

简介

EF Core 中的索引器属性(Indexer Property)是指通过一个特殊的属性来访问实体类中的数据,而不必明确声明实体属性。这种属性在一些动态或未预定义的场景中非常有用,比如当实体的属性名在编译时并不确定,或者属性名集合较大时。

场景及应用

1.动态属性访问
索引器属性最常见的应用场景是动态属性访问。这在处理 JSON 数据或其他半结构化数据时尤其有用。例如,当你有一个属性名称集合在编译时并不确定,或者从外部源(如配置文件、API 响应等)中获取属性名时,可以使用索引器属性来动态访问这些属性。

2.字典数据结构
如果实体类包含一个字典类型的属性,可以通过索引器属性来访问字典中的数据。例如,如果你的实体中包含了一个 Dictionary<string, object> 来存储额外的数据,使用索引器属性可以简化访问这些数据的方式。

public class DynamicEntity
{private Dictionary<string, object> _additionalData = new Dictionary<string, object>();public object this[string key]{get => _additionalData.ContainsKey(key) ? _additionalData[key] : null;set => _additionalData[key] = value;}
}

3.元数据处理
在一些应用场景中,需要将不同的元数据存储在实体中而不增加额外的列。在这种情况下,可以使用索引器属性来处理这些元数据。例如,当你需要根据业务逻辑在数据库表中存储额外的、可变的属性集合时,可以使用索引器属性来管理这些属性。

4.简化代码
索引器属性可以简化代码,减少显式声明属性的需求。在开发过程中,减少了重复代码,提高了代码的可维护性和灵活性。

EF Core 配置

在 EF Core 中使用索引器属性时,需要在模型配置阶段进行一些特殊的配置,以确保 EF Core 正确地将索引器属性映射到数据库字段。这里我们讨论几种常见的配置方法。

1. 使用 Dictionary<string, object> 的索引器属性

如果你在实体类中使用了 Dictionary<string, object> 作为索引器属性的存储机制,并希望 EF Core 将这些键值对存储在数据库表的专用列中,可以按照以下方式配置:

实体类示例

public class Product
{public int Id { get; set; }public string Name { get; set; }private Dictionary<string, object> _extendedProperties = new Dictionary<string, object>();public object this[string key]{get => _extendedProperties.ContainsKey(key) ? _extendedProperties[key] : null;set => _extendedProperties[key] = value;}
}

OnModelCreating 方法中配置

DbContext 中的 OnModelCreating 方法中配置索引器属性。你可以使用 OwnsMany 来配置字典的映射。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{modelBuilder.Entity<Product>().OwnsMany(p => p._extendedProperties, a =>{a.Property<string>("Key");a.Property<string>("Value");a.WithOwner().HasForeignKey("ProductId");a.ToTable("ProductExtendedProperties");});
}

此配置将 Product 实体的扩展属性存储在一个单独的表 ProductExtendedProperties 中,该表将有三列:ProductIdKeyValue

2. 直接将索引器属性映射到表的列

如果你希望直接将索引器属性映射到表的列(而不是将字典存储在单独的表中),你可以使用 Property 方法来配置。

实体类示例

public class MultilingualContent
{private Dictionary<string, string> _translations = new Dictionary<string, string>();public int Id { get; set; }public string this[string language]{get => _translations.ContainsKey(language) ? _translations[language] : null;set => _translations[language] = value;}
}

OnModelCreating 方法中配置

protected override void OnModelCreating(ModelBuilder modelBuilder)
{modelBuilder.Entity<MultilingualContent>().Property(e => e["en"]).HasColumnName("EnglishContent");modelBuilder.Entity<MultilingualContent>().Property(e => e["fr"]).HasColumnName("FrenchContent");
}

这种配置将索引器属性中不同语言的内容直接映射到 MultilingualContent 表中的不同列(如 EnglishContentFrenchContent)。

3. 映射到 JSON 列

EF Core 5.0 开始支持将复杂类型映射到 JSON 列中。如果你使用索引器属性存储复杂对象,可以将其映射为 JSON。

实体类示例

public class Configuration
{private Dictionary<string, string> _settings = new Dictionary<string, string>();public int Id { get; set; }public string this[string key]{get => _settings.ContainsKey(key) ? _settings[key] : null;set => _settings[key] = value;}
}

OnModelCreating 方法中配置

protected override void OnModelCreating(ModelBuilder modelBuilder)
{modelBuilder.Entity<Configuration>().Property(e => e._settings).HasColumnType("jsonb").HasColumnName("Settings");
}

这种配置将整个字典映射为一个 JSON 字段,可以灵活存储复杂和动态的数据结构。

完整实例之-多语言支持

在处理多语言支持的案例中,配置好 EF Core 后,你可以通过索引器属性动态地访问和更新不同语言的内容。下面将详细说明如何调用和请求使用这个多语言支持的模型。

1. 设置数据库上下文和实体

首先,假设你已经按照前面的指导配置好了 MultilingualContent 实体和数据库上下文。这里是完整的实体类和上下文的代码:

实体类 MultilingualContent

public class MultilingualContent
{private Dictionary<string, string> _translations = new Dictionary<string, string>();public int Id { get; set; }public string this[string language]{get => _translations.ContainsKey(language) ? _translations[language] : null;set => _translations[language] = value;}
}

数据库上下文 AppDbContext

public class AppDbContext : DbContext
{public DbSet<MultilingualContent> MultilingualContents { get; set; }protected override void OnModelCreating(ModelBuilder modelBuilder){modelBuilder.Entity<MultilingualContent>().Property(e => e["en"]).HasColumnName("EnglishContent");modelBuilder.Entity<MultilingualContent>().Property(e => e["fr"]).HasColumnName("FrenchContent");// 配置其他语言...}
}

2. 添加数据

假设你需要为一段内容添加英语和法语版本。你可以使用索引器属性来设置这些语言的内容。

using (var context = new AppDbContext())
{var content = new MultilingualContent();content["en"] = "Hello, world!";content["fr"] = "Bonjour, le monde!";context.MultilingualContents.Add(content);context.SaveChanges();
}

上面的代码会在数据库中插入一条记录,其中包含英语和法语的文本。

3. 检索数据

假设你想要根据语言检索某段内容。可以使用索引器属性来获取相应语言的文本。

using (var context = new AppDbContext())
{var content = context.MultilingualContents.FirstOrDefault(c => c.Id == 1);if (content != null){string englishText = content["en"];string frenchText = content["fr"];Console.WriteLine($"English: {englishText}");Console.WriteLine($"French: {frenchText}");}
}

这段代码会从数据库中检索 ID 为 1 的内容,并输出其英语和法语版本。

4. 更新数据

你可以使用索引器属性来更新某个语言的内容。

using (var context = new AppDbContext())
{var content = context.MultilingualContents.FirstOrDefault(c => c.Id == 1);if (content != null){content["en"] = "Hello, everyone!";content["fr"] = "Bonjour, tout le monde!";context.SaveChanges();}
}

这段代码会更新 ID 为 1 的内容,将英语和法语文本分别更新为新的内容。

5. 删除数据

删除操作和普通的实体一样,可以使用 EF Core 提供的标准方法。

using (var context = new AppDbContext())
{var content = context.MultilingualContents.FirstOrDefault(c => c.Id == 1);if (content != null){context.MultilingualContents.Remove(content);context.SaveChanges();}
}

这段代码会从数据库中删除 ID 为 1 的内容及其所有语言版本的文本。

总结

EF Core 的索引器属性对于处理动态属性、元数据、或结构化但不固定的属性集合非常有用。它能够提高代码的灵活性和可维护性,特别是在处理需要存储可变属性的场景时。

END 欢迎关注 "ShareFlow" 公众号

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/781638.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

EPIC Institute of Technology Round August 2024 (Div. 1 + Div. 2) 补题记录(A~D1,E)

A 容易发现答案为 \(\min(n,k)\min(m,k)\)。 #include<bits/stdc++.h> #define int long long #define pb push_back using namespace std; const int N=1000100; int a[N]; signed main(){int T;cin>>T;while(T--){int n,m,k;cin>>n>>m>>k;n=mi…

后端开发学习敏捷需求--干系人分析与识别

干系人分析与识别 5W1H 干系人分析与识别 1. 干系人是什么直接或者间接影响专题,以及被专题影响的人和组织,用户也是属于干系人,是产品直接或者间接的使用者又叫利益相关者,指积极参与专题或者在专题中其利益可能受积极或消极影响的个人或组织2. 为什么要分析和识别干系人找…

while循环的3个练习

static void Main(string[] arg){//while的3个练习Console.WriteLine("请输入班级人数:");int intNum = 0;while (!(int.TryParse(Console.ReadLine(), out intNum))){Console.WriteLine("班级人数输入有误, 请重新输入!");};int i = 0;int sum = 0;int sc…

地理编码之旅,一场地址与坐标的漫游

随着移动设备的普及和定位服务的发展,在使用导航和位置搜索时,用户期望应用提供的位置是准确无误的,同时用户也希望App可以根据位置提供个性化和本地化服务,比如,在社交媒体上分享位置信息或帮助家庭设备智能联网管理等。想要获取准确的位置,经纬度是确定每个地点位置的精…

结构开发笔记(三):solidworks软件(二):小试牛刀,绘制一个立方体

前言solidworks草图大师,基本的使用过程。  所有的零件基础都是从平面绘制开始,然后凸出来厚度。  本篇绘制一个简单的立方体,熟悉基本操作。 立方体绘制过程选取一个平面绘制一个立方形,然后拉伸即可。  绘制矩形的方式:  功能所见即所得。  其实用2021版本,还…

面经精选:数据库高频面试十问

我把粉丝们发给我的面经好好整理了一下,从里面挖出了十个被问得比较频繁的数据库面试题,可以收藏起来,在面试之前给它突击过一遍。1.InnoDB和MyISAM存储引擎的区别? MySQL 默认的存储引擎是 InnoDB,它采用 B+Tree 作为索引的数据结构。 在创建表时,InnoDB 存储引擎默认会…

Opentelemetry collector用法

Opentelemetry collector用法 目录Opentelemetry collector用法ServiceExtensionshealthcheckextensionPipelinesreceiverOTLP Receiverprometheus receiverfilelog receiverProcessor数据归属Importantmemory limiter processorbatch processorattributes processor &&…

记录JSch连接SFTP Exception:Algorithm negotiation fail问题解决

问题描述:关于正式环境访问外网连接不成功 1、首先检查是否开放防火墙(已确认开放),策略开放后,通过命令连接是否畅通: 通过telnet命令,可以得出,访问畅通。telnet 192.168.1.1 22 2、查看生产环境日志,观察生产环境访问外网服务器异常: 抛出异常,提示:算法协商失…

zkw线段树

zkw 线段树 - 非递归线段树实现方法介绍 非递归线段树实现方法,码量较短。 zkw 线段树的构造原理: 普通线段树采用堆存储,zkw线段树 本质上是满二叉树(若没有该区间则为空点) 但根据实际情况,原区间不一定构成满二叉树,据查询方式限制,空间开到最接近的 \(2^n\)(据性质…

张昆玮线段树

zkw 线段树 - 非递归线段树实现方法介绍 非递归线段树实现方法,码量较短。 zkw 线段树的构造原理: 普通线段树采用堆存储,zkw线段树 本质上是满二叉树(若没有该区间则为空点) 但根据实际情况,原区间不一定构成满二叉树,据查询方式限制,空间开到最接近的 \(2^n\)(据性质…

全红婵夺冠!数业智能心大陆告诉你原生家庭在背后发挥了怎样的力量

2024年巴黎,全红婵在十米跳台上的完美一跃, 再次定义了跳水艺术,水花消失术成为她的代名词!全红婵的辉煌成就,不仅点亮了自己,也照亮了家庭的未来。 而他的家人也非常珍视全红婵的成功。 其父亲坚定的表示:”我们不能消费女儿“。 “不能因为她拿了冠军,我连活都不干了。…

无缝融入,即刻智能[一]:Dify-LLM大模型平台,零编码集成嵌入第三方系统,42K+星标见证专属智能方案[含ollama部署]

无缝融入,即刻智能[一]:Dify-LLM大模型平台,零编码集成嵌入第三方系统,42K+星标见证专属智能方案-含ollama部署无缝融入,即刻智能[一]:Dify-LLM大模型平台,零编码集成嵌入第三方系统,42K+星标见证专属智能方案 1.Dify 简介 1.1 功能情况 Dify,一款引领未来的开源大语言…