在现有 SQL Server 数据库上使用实体框架时禁用 VARCHAR 和 NVARCHAR 之间的转换
Posted
技术标签:
【中文标题】在现有 SQL Server 数据库上使用实体框架时禁用 VARCHAR 和 NVARCHAR 之间的转换【英文标题】:Disable conversion between VARCHAR and NVARCHAR when using Entity Framework over an existing SQL server database 【发布时间】:2018-08-25 18:40:59 【问题描述】:我有一个现有的数据库 SQL 服务器,我正在使用 EF6。假设我有以下代码:
private sealed class Foo
public int Id get; set;
public string Bar get; set;
private sealed class FooConfiguration : EntityTypeConfiguration<Foo>
public FooConfiguration()
ToTable("Foos");
HasKey(e => e.Id);
Property(e => e.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
private class FooContext : DbContext
public FooContext(string connectionString)
: base(connectionString)
Database.SetInitializer<FooContext>(null);
public virtual DbSet<Foo> Foos get; set;
protected override void OnModelCreating(DbModelBuilder modelBuilder)
base.OnModelCreating(modelBuilder);
modelBuilder.Configurations.Add(new FooConfiguration());
用法:
const string bar = "حالياً البحث عبر جوجل";
int fooId;
using (var db = new FooContext(connectionString))
var foo = db.Foos.Add(new Foo Bar = bar );
db.SaveChanges();
fooId = foo.Id;
using (var db = new FooContext(connectionString))
var foo = db.Foos.First(f => f.Id == fooId);
if (foo.Bar != bar)
Console.WriteLine("Oops!");
什么可能出错?好吧,如果Bar
列的类型是VARCHAR(MAX)
而不是NVARCHAR(MAX)
,那么我们就处于不利的位置,因为VARCHAR
无法正确存储该Unicode 字符串,所以我们得到了一堆问号。
所以,问题是:我可以如何禁用VARCHAR
和NVARCHAR
之间的这种转换并强制EF 在SaveChanges
期间抛出某种类型不匹配异常吗?我尝试在我的配置类中使用它:
Property(e => e.Bar).IsUnicode(true);
Property(e => e.Bar).HasColumnType("NVARCHAR(MAX)");
但它什么也没做。
提前致谢。
【问题讨论】:
这听起来更像是一个 xy 问题。如果您需要确保存储 unicode 字符,那么您需要确保正确声明数据类型。如果您因为使用了错误的数据类型而丢失了数据,那不是应用程序或数据引擎的错;就是需要正确配置数据类型。 @Larnu 你说得对,这是我的数据库中类型不正确的问题,而不是应用程序代码。在我们在“Foos”表中插入无数行之前,我只是在寻找一种可以帮助我找到这些问题的解决方案 这是代码优先吗? this question 中有一些指针(和一个库),它基本上以更一般的方式询问您要问的内容,但对于 Code First,您可能会受到影响,因为 EF 不会费力地检索元数据并首先比较注释.请注意,这实际上是一个非常困难的问题。如果无法假设您的数据库与您的模型匹配(当然,一些架构差异是良性的,但这取决于应用程序),那么大多数数据访问都是无效或低效的。 【参考方案1】:string
列的默认数据类型为nvarchar(MAX)
,您无需在列中设置数据类型即可更改为NVARCHAR(MAX)
。 Ef 具有指定它的默认约定。 here 解释为了解约定。
如果你想为你的模型配置一般约定,你可以这样做:
public class DataTypeConvention : Convention
public DataTypeConvention()
Properties<string>().Configure(config => config.HasColumnType("nvarchar(MAX)"); );
在您的 DbContext 上:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
modelBuilder.Conventions.Add(new DataTypeConvention());
【讨论】:
以上是关于在现有 SQL Server 数据库上使用实体框架时禁用 VARCHAR 和 NVARCHAR 之间的转换的主要内容,如果未能解决你的问题,请参考以下文章
如何更改实体框架项目以使用 Microsoft SQL Server
同时将实体框架与 SQL Server 和 SQLite 数据库一起使用
使用 SQL Server 数据库和实体框架错误的 Windows 应用程序部署