如何使用 Entity Framework Core 保留字符串列表? [英] How to persist a list of strings with Entity Framework Core?

查看:18
本文介绍了如何使用 Entity Framework Core 保留字符串列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们有一个类,如下所示:

Let us suppose that we have one class which looks like the following:

public class Entity
{
    public IList<string> SomeListOfValues { get; set; }

    // Other code
}

现在,假设我们想使用 EF Core Code First 来持久化这一点,并且我们使用的是像 SQL Server 这样的 RDMBS.

Now, suppose we want to persist this using EF Core Code First and that we are using a RDMBS like SQL Server.

一种可能的方法显然是创建一个包装类 Wraper 来包装字符串:

One possible approach is obviously to create a wraper class Wraper which wraps the string:

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

    public string Value { get; set; }
}

并重构该类,使其现在依赖于 Wraper 对象列表.在这种情况下,EF 将为 Entity 生成一个表,为 Wraper 生成一个表并建立一对多"关系:对于每个实体,都有一堆包装器.

And to refactor the class so that it now depends on a list of Wraper objects. In that case EF would generate a table for Entity, a table for Wraper and stablish a "one-to-many" relation: for each entity there is a bunch of wrapers.

虽然这有效,但我不太喜欢这种方法,因为出于持久性考虑,我们正在更改一个非常简单的模型.确实,仅考虑域模型和代码,如果没有持久性,Wraper 类在那里毫无意义.

Although this works, I don't quite like the approach because we are changing a very simple model because of persistence concerns. Indeed, thinking just about the domain model, and the code, without the persistence, the Wraper class is quite meaningless there.

除了创建包装器类之外,还有其他方法可以使用 EF Core Code First 将带有字符串列表的实体持久化到 RDBMS 吗?当然,最后必须做同样的事情:必须创建另一个表来保存字符串,并且必须建立一对多"关系.我只想用 EF Core 做到这一点,而无需在域模型中编写包装类.

Is there any other way persist one entity with a list of strings to a RDBMS using EF Core Code First other than creating a wraper class? Of course, in the end the same thing must be done: another table must be created to hold the strings and a "one-to-many" relationship must be in place. I just want to do this with EF Core without needing to code the wraper class in the domain model.

推荐答案

这可以从 Entity Framework Core 2.1 开始以更简单的方式实现.EF 现在支持价值转换来专门解决这样的场景需要将属性映射到不同类型以进行存储.

This can be achieved in a much more simple way starting with Entity Framework Core 2.1. EF now supports Value Conversions to specifically address scenarios like this where a property needs to be mapped to a different type for storage.

要持久化一组字符串,您可以通过以下方式设置您的 DbContext:

To persist a collection of strings, you could setup your DbContext in the following way:

protected override void OnModelCreating(ModelBuilder builder)
{
    var splitStringConverter = new ValueConverter<IEnumerable<string>, string>(v => string.Join(";", v), v => v.Split(new[] { ';' }));
    builder.Entity<Entity>().Property(nameof(Entity.SomeListOfValues)).HasConversion(splitStringConverter);
} 

请注意,此解决方案不会让您的商务舱因 DB 问题而烦恼.

Note that this solution does not litter your business class with DB concerns.

不用说,这个解决方案必须确保字符串不能包含分隔符.但当然,可以使用任何自定义逻辑进行转换(例如,从/到 JSON 的转换).

Needless to say that this solution, one would have to make sure that the strings cannot contains the delimiter. But of course, any custom logic could be used to make the conversion (e.g. conversion from/to JSON).

另一个有趣的事实是,空值不是传递到转换例程中,而是由框架本身处理.因此无需担心转换例程中的空检查.但是,如果数据库包含 NULL 值,则整个属性将变为 null.

Another interesting fact is that null values are not passed into the conversion routine but rather handled by the framework itself. So one does not need to worry about null checks inside the conversion routine. However, the whole property becomes null if the database contains a NULL value.

这篇关于如何使用 Entity Framework Core 保留字符串列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆