微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决EF Core 3.1无法查询Json序列化对象

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

型号:

public class Video
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual IList<int> AllRelatedIds { 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 })
    );
});

它工作正常,添加,编辑,删除项目很容易,并且在sql数据库中像json一样存储为
[11000,12000,13000]

一切都很好,但是!想要在此列表上查询时,我会得到奇怪的答复。

位置:

_context.Set<Video>().Where(t=>t.AllRelatedIds.contains(11000)) 返回,但是,如果我要求返回所有 AllRelatedIds 项,则某些记录的exp值为11000。

计数:

_context.Set<Video>().Count(t=>t.AllRelatedIds.contains(11000))返回无法翻译。以可转换的形式重写查询,或者通过插入对AsEnumerable(),AsAsyncEnumerable(),ToList()或ToListAsync()的调用来显式切换到客户端评估。

EF Core有什么问题?我什至测试了t=>t.AllRelatedIds.ToList().contains(11000),但没有改变

我该怎么办?我不想有更多的表,我已经使用了数百次这种方法,但似乎从未对其查询

解决方法

Json序列化/反序列化发生在应用程序级别。 EF Core将IList<int>对象序列化为值[11000,12000,13000] ,然后将其发送到数据库进行存储,并将值[11000,13000]反序列化为IList<int>对象之后从数据库中检索它。数据库内部什么也没有发生。您的数据库无法在[11000,13000]上作为数字的集合进行操作。对于数据库,它是一条数据。

如果您尝试以下查询-

var videos = _context.Set<Video>().ToList();
var video = _context.Set<Video>().FirstOrDefault(p=> p.Id == 2);

您将获得预期的结果,EF Core可以完美地完成工作。

问题是,当您查询类似-

_context.Set<Video>().Where(t=> t.AllRelatedIds.Contains(11000))

EF Core将无法将t.AllRelatedIds.Contains(11000)部分转换为SQL。 EF Core只能对其进行序列化/反序列化,因为您已告知它(以及如何)。但是如上所述,您的数据库无法作为整数的集合在[11000,13000]上进行操作。因此,EF Core无法将t.AllRelatedIds.Contains(11000)转换为对数据库有意义的任何内容。

一种解决方案是获取所有视频的列表,以便EF Core可以将AllRelatedIds反序列化为IList<int>,然后可以在其上应用LINQ-

var allVideos = _context.Set<Video>().ToList();
var selectedVideos = allVideos.Where(t=> t.AllRelatedIds.Contains(11000)).ToList();

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。