【问题标题】:Invalid characters (??) inserted in the middle of email value在电子邮件值中间插入无效字符 (??)
【发布时间】:2020-08-31 18:53:08
【问题描述】:

EF Core 正在为电子邮件列保存错误的值。

例如:属性类有一个字符串值:pna@pn.com.br

但是当我检查存储的值时(在 SQL Server 中并使用 EF Core 获取对象)是:pna@pn.com??.br

?? 不存在于原始电子邮件值中。

我已经直接插入数据库了,但是没有出现这个问题。

重现步骤:

尝试使用 EF Core 进行简单插入,如下所示:

我的存储库类中的插入方法:

public void Insert(T entity)
{
       DbContext.Set<T>().Add(entity);
       DbContext.SaveChanges();
}

我的映射实体类:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using DataImoveis.Domain.Entities.Abstraction;

namespace DataImoveis.Domain.Entities
{
    [Table("SIL_IMOVEL_INQUILINO")]
    public class ImovelInquilino : BaseEntity
    {
        [Key]
        [Column("cod")]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Cod { get; set; }

        [Column("propertyId")]
        public int PropertyId { get; set; }

        [Column("lastUpdatedDate")]
        public DateTime LastUpdatedDate { get; set; }

        [Column("tenantName")]
        public string TenantName { get; set; }

        [Column("tenantContact")]
        public string TenantContact { get; set; }

        [Column("tenantEmail")]
        public string TenantEmail { get; set; }

        [Column("tenantPhone")]
        public string TenantPhone { get; set; }

        [Column("tenantIndustry")]
        public string TenantIndustry { get; set; }
    }
}

我的 DbContext 类:

using DataImoveis.Domain.Entities;
using DataImoveis.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.Options;

namespace DataImoveis.Infrastructure
{
    public class DbContext : Microsoft.EntityFrameworkCore.DbContext
    {
        public virtual DbSet<ImovelInquilino> ImovelInquilino { get; set; }

        private IOptions<Settings> settings;

        public override DatabaseFacade Database { get { return base.Database; } }

        public DbContext(IOptions<Settings> settings) : base() =>
            this.settings = settings;

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(
                settings.Value.ConnectionStrings.DefaultConnection
            );
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder) { }

    }
}

数据库中的列详细信息:

[tenantEmail] [varchar](70) NULL,

此字段没有触发器或以后更新。

我为DbContext 操作启用了日志记录,以检查从 EF Core 发送到数据库的参数,我认为一切正常:

Executed DbCommand (24ms) [Parameters=[(...) @p14='pna@pn.com​​.br.' (...)]

更多技术细节

  • EF Core 版本:3.1.4
  • 数据库提供程序:Microsoft.EntityFrameworkCore.SqlServer 3.1.3
  • 数据库:SQL Server 2019
  • 目标框架:.NET Core 3.1
  • 操作系统:Ubuntu 18.04(在 WSL2 中)或 Windows 10
  • IDE:VSCode

【问题讨论】:

  • varchar 是 ascii,nvarchar 是 unicode
  • 我只是将此文本复制粘贴到交互式 C# 窗口以查看长度:"pna@pn.com​​.br.".Length。结果是16.com 后面有两个不可见字符。
  • 感谢您的帮助!问题就像你说的那样。我什至注意到,因为 a 非常专注于 SQL Server 和 EFCore。谢谢!

标签: c# sql-server .net-core entity-framework-core


【解决方案1】:

您的电子邮件地址在“com”和“.br”之间有两个 Unicode 字符“零宽度空格”(E2 80 8B)。 (我将您日志中的文本复制到文本文件中,保存并查看十六进制表示:

由于 DB 列是 varchar,这些 un​​icode 字符无法按原样保存在 DB 中,DB 将它们转换为占位符'?'。

要么将 DB 列定义为 nvarchar(并且所有 Unicode 字符都将按原样存储),要么从输入数据中删除此类字符。

【讨论】:

  • 感谢您对我的帮助以及您如此迅速的回复。我非常专注于 SQL Server 和实体框架问题,甚至注意到了这个小细节。我用正则表达式转义了内容字符串: content = Regex.Replace(content, @"[^\u0000-\u007F]+", string.Empty);
猜你喜欢
  • 2013-02-02
  • 2019-05-20
  • 2023-03-20
  • 1970-01-01
  • 2012-12-12
  • 1970-01-01
  • 2015-05-07
  • 2016-09-22
  • 1970-01-01
相关资源
最近更新 更多