Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架核心-高效地在数据库中存储/查询多语言记录_C#_Entity Framework Core - Fatal编程技术网

C# 实体框架核心-高效地在数据库中存储/查询多语言记录

C# 实体框架核心-高效地在数据库中存储/查询多语言记录,c#,entity-framework-core,C#,Entity Framework Core,我正在构建一个必须支持多种语言的应用程序 因此,我数据库中的一些记录需要每种语言有多个版本 我首先解释一下我是如何实现这一点的:考虑一个名为“代码>区域的实体,它代表一个地理位置,并有一个简单的名称。 我会这样设计我的实体: public class Region { public int Id { get; set; } public List<RegionLanguage> Languages { get;set; } } public class Regi

我正在构建一个必须支持多种语言的应用程序

因此,我数据库中的一些记录需要每种语言有多个版本

我首先解释一下我是如何实现这一点的:考虑一个名为“代码>区域<代码>的实体,它代表一个地理位置,并有一个简单的名称。 我会这样设计我的实体:

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

    public List<RegionLanguage> Languages { get;set; }
}

public class RegionLanguage 
{
    public Region Region { get;set; } // Parent record this language applies to
    public string CultureCode { get; set; } // Will store culture code such as en-US or fr-CA

    // This column/property will be in the language specified by Culturecode
    [StringLength(255)]
    public string Name { get;set; }
}
您可以看到,这会变得效率低下,因为我必须包含正在获取的实体的所有语言记录,而实际上我只需要一个记录,然后在内存中搜索正确的语言。当然,当我需要获取
区域的列表时,情况会变得更糟,而这些区域必须返回大量不必要的数据

当然,可以直接使用SQL,只需在
join
语句中添加一个额外的子句:

select * 
from Regions 
left join RegionLanguage on (RegionLanguage.Region = Regions.Id and RegionLanguage.CultureCode = 'en-US')
然而,据我所知,如果不使用
RawQuery
()


这就引出了一个问题:有没有更好的方法来使用EF Core实现数据库中的多语言记录?或者我应该继续我的方法,并希望EF Core在我的应用程序实际需要时实现
包括
过滤(我承认我可能会过早地进行优化,但我真的很好奇是否有更好的方法来实现这一点)。

您可以使用投影

var languageRegion = await _context.Regions
.Select(p => new Region
{
     Languages = p.Languages.FirstOrDefault(e => e.CultureCode == "en-US")
}.FirstOrDefaultAsync(e => e.Id == 34);

如果区域和语言不经常更改,您可以使用缓存。

您可以使用投影

var languageRegion = await _context.Regions
.Select(p => new Region
{
     Languages = p.Languages.FirstOrDefault(e => e.CultureCode == "en-US")
}.FirstOrDefaultAsync(e => e.Id == 34);
如果区域和语言不经常更改,您可以使用缓存。

您可以使用

模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
实体(生成器=>
{
builder.haskqueryfilter(rl=>rl.CultureCode==“en-US”);
});
}
您可以使用

模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
实体(生成器=>
{
builder.haskqueryfilter(rl=>rl.CultureCode==“en-US”);
});
}

您是否尝试过使用左连接linq查询?您是否尝试过使用左连接linq查询?我已经研究过了,但它似乎不是很优雅。硬编码“en-US”将不起作用,在链接页面上使用类似于_-tenantId的示例会增加大量的复杂性,因为您需要注入一个决定要使用的区域性的服务,该服务依赖于HttpContext,因此现在您的数据层依赖于HttpContext,这是非常不需要的。不确定您的需求。
cultureCode
是否会在运行时更改?如果是,怎么做?如果没有,您可以在配置文件上定义
cultureCode
,然后根据区域应用配置转换,这样您就不会硬编码它。是的,它将根据使用Accept Language HTTP头的请求而改变。这完全取决于当前用户使用的语言您必须使用第三方的
Include
过滤器,因为EF Core还不支持它。我已经研究过这一点,但它似乎不是很优雅。硬编码“en-US”将不起作用,在链接页面上使用类似于_-tenantId的示例会增加大量的复杂性,因为您需要注入一个决定要使用的区域性的服务,该服务依赖于HttpContext,因此现在您的数据层依赖于HttpContext,这是非常不需要的。不确定您的需求。
cultureCode
是否会在运行时更改?如果是,怎么做?如果没有,您可以在配置文件上定义
cultureCode
,然后根据区域应用配置转换,这样您就不会硬编码它。是的,它将根据使用Accept Language HTTP头的请求而改变。这完全取决于当前用户使用的语言您必须使用第三方的
Include
过滤器,因为EF Core还不支持它。这似乎更有效,但我并不热衷于在我的大多数查询中编写投影。是否可以只投影Languages属性,而仍自动投影所有其他属性?如果只想读取值,因为选择读取会导致不跟踪实体,则选择读取是最有效的解决方案。您也可以阅读其他属性,只需在select命令中添加相关实体即可。这似乎更有效,但我并不热衷于在大多数查询中编写投影。是否可以只投影Languages属性,而仍自动投影所有其他属性?如果只想读取值,因为选择读取会导致不跟踪实体,则选择读取是最有效的解决方案。您也可以读取其他属性,只需在select命令中将相关实体添加到。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<RegionLanguage>(builder =>
    {
        builder.HasQueryFilter(rl => rl.CultureCode == "en-US");
    });
}