Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.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
Sql server EF Core 3.1无法查询Json序列化对象_Sql Server_Entity Framework_Asp.net Core_Entity Framework Core_Jsonserializer - Fatal编程技术网

Sql server EF Core 3.1无法查询Json序列化对象

Sql server EF Core 3.1无法查询Json序列化对象,sql-server,entity-framework,asp.net-core,entity-framework-core,jsonserializer,Sql Server,Entity Framework,Asp.net Core,Entity Framework Core,Jsonserializer,我使用json序列化将列表存储在字段中的ID上 型号: public class Video { public int Id { get; set; } public string Name { get; set; } public virtual IList<int> AllRelatedIds { get; set; } } 公开课视频 { 公共int Id{get;set;} 公共字符串名称{get;set;} 公共虚拟IList AllRelate

我使用json序列化将列表存储在字段中的ID上

型号:

public class Video
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual IList<int> AllRelatedIds { get; set; }
}

公开课视频
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共虚拟IList AllRelatedId{get;set;}
}
背景:

modelBuilder.Entity<Video>(entity =>
{
    entity.Property(p => p.AllRelatedIds).HasConversion(
    v => JsonConvert.SerializeObject(v, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }),
    v => JsonConvert.DeserializeObject<IList<int>>(v, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore })
    );
});
modelBuilder.Entity(Entity=>
{
Property(p=>p.AllRelatedId).HasConversion(
v=>JsonConvert.SerializeObject(v,新的JsonSerializerSettings{NullValueHandling=NullValueHandling.Ignore}),
v=>JsonConvert.DeserializeObject(v,新的JsonSerializerSettings{NullValueHandling=NullValueHandling.Ignore})
);
});
它工作得很好,添加、编辑和删除项目都很容易,并且在SQL数据库中它以类似json的形式存储
[11000120001300]

一切都很好,但是!!我一想查询这个列表,就会收到奇怪的回复

其中:

\u context.Set().Where(t=>t.AllRelatedIds.contains(11000))
返回null但是如果我要求返回所有AllRelatedIds项,一些记录的exp值为11000

计数:

\u context.Set().Count(t=>t.AllRelatedIds.contains(11000))
返回无法翻译。以可翻译的形式重写查询,或者通过插入对AsEnumerable()、AsAsAsAsyncEnumerable()、ToList()或ToListSync()的调用显式切换到客户端计算。

EF Core怎么了?我甚至测试了
t=>t.AllRelatedIds.ToList().contains(11000)
,但没有任何区别


我该怎么办?我不想有更多的表,我使用了这种方法数百次,但似乎从未对它们进行过查询。

Json序列化/反序列化发生在应用程序级别。EF Core将
IList
对象序列化为值
[11000120001300]
,然后将其发送到数据库进行存储,并在从数据库检索值
[11000120001300]
后将其反序列化为
IList
对象。数据库内部没有发生任何事情。您的数据库不能在
[11000120001300]
上作为数字集合运行。对于数据库来说,它只是一个数据块

如果您尝试以下查询-

var videos=_context.Set().ToList();
var video=_context.Set().FirstOrDefault(p=>p.Id==2);
您将得到预期的结果,EF Core正在完美地完成它的工作

问题是,当您查询以下内容时-

\u context.Set()。其中(t=>t.allrelatedId.Contains(11000))
EF Core将无法将
t.allrelatedId.Contains(11000)
部分转换为SQL。EF Core只能对其进行序列化/反序列化,因为您告诉了它(以及如何进行)。但正如我上面所说,您的数据库不能作为整数集合在
[11000120001300]
上运行。因此EF Core无法将
t.allrelatedId.Contains(11000)
转换为对数据库有意义的任何内容

解决方案是获取所有视频的列表,以便EF Core可以将
allrelatedId
反序列化为
IList
,然后您可以对其应用LINQ-

var allVideos=\u context.Set().ToList();
var selectedVideos=allVideos.Where(t=>t.AllRelatedIds.Contains(11000)).ToList();

但是,从性能角度看,每次获取所有视频不是不必要/过度或效率低下吗?当然可以。但正如评论所暗示的,您的数据库设计/使用方法存在一些缺陷。

我不得不问,这个数据库有什么问题?您是否尝试将ID存储在JSON字段而不是多对多表中?这是一个明显的数据库设计缺陷。EF是一个ORM,它将对象映射到关系结构,它不能做数据库中不可能的事情。使用多对多表是简单、干净和易于管理的。将所有内容都塞进一个字段都不是,因为它违反了最基本的设计规则——一个字段,一个值。现在不可能使用SQL连接、过滤或查询该字段,如果您使用SQL Server 2016及更高版本,您可以使用JSON函数(JSON_query,JSON_VALUE)来使用该字段,并且您仍然会得到非常糟糕的性能,因为这些值无法被索引。如果您有一个像Oracle这样支持阵列的数据库,您可以使用
VARRAY
,但性能仍然会受到影响
我不想有更多的表,
为什么
只要您想查询此列表
您没有列表,您就有一个长的不透明字符串,某些函数可以解析它。如果数据库设计正确,甚至可以使用查找多个级别的相关视频。通过使用那个长字符串,您甚至不能在中查询单个值SQL@PanagiotisKanavos我不想在不重要的项目上使用太多的关系,也不想进行sql查询,只想让它们像逗号一样分开enough@PanagiotisKanavos你是对的,我必须把它们存储在数据库中