5 回答
TA贡献1828条经验 获得超3个赞
错误消息表明 EF Core 正在尝试读取所需string
属性的值,即不应在数据库中具有值的属性,而是底层数据读取器在某些记录中报告该属性的值。null
null
查看您的实体模型和相应的数据库表,您可以看到许多string
属性 ->varchar
列的明显差异。CompanyStreetAddress
, CompanyCity
, CompanyZipCode
, CompanyVatNumber
, ContactFirstName
, ContactLastName
- 所有这些都[Required]
在模型中标记为,但在表中没有相应not null
的约束。
所以问题是由这些列中的一个或多个引起的。
您需要修复该差异 - 可能通过删除[Required]
属性来解决,因为现有数据中的约束已被破坏。
它在某些较旧的 EF Core 版本中“有效”这一事实并不重要——这是不正确的映射,因此应该修复。从技术上讲,它不应该从一开始就起作用。但请记住,EF Core 仍在积极开发中,并且有许多错误将在下一个版本中修复。很可能在“工作”和“非工作”EF Core 版本之间进行了一些代码更改,这修复了以前的不正确行为。
TA贡献1840条经验 获得超5个赞
如果您尝试从数据库中读取一些可为空的数据,但您的类型不可为空,则可能会出现此错误。
如果MyInt在数据库中可以为空并且您有此实体:
public class MyEntity
{
public int Id { get; set; }
public int MyInt { get; set; }
}
你会得到例外:System.Data.SqlTypes.SqlNullValueException: 'Data is Null. This method or property cannot be called on Null values.'
MyInt要解决此问题,只需将属性的类型更改为Nullable<int>or int?:
public class MyEntity
{
public int Id { get; set; }
public int? MyInt { get; set; }
}
注意:这不是对原问题的回答,而是对标题中问题的回答。
TA贡献1872条经验 获得超3个赞
如果您从 C# 8 启用最新的 Nullable 功能,也会出现这种异常。
EF Core,至少目前,它与 C# 8 可空类型不完全兼容。因此,例如,假设您为项目启用了 Nullable 功能,如果您有这样的类型:
public class MyEntity{ public string MyProperty { get; set; } }
即使该属性未标记 [Required] 属性,EF 核心也会引发此类异常,因为它要求数据库中的值不为空(即它不使用 IsDbNull 测试列值)。
有关如何在 EF 核心中处理可空引用类型的更多信息,请查看: https ://learn.microsoft.com/en-us/ef/core/miscellaneous/nullable-reference-types
TA贡献1844条经验 获得超8个赞
为了解决类似的Data is Null
异常问题,我必须明确地放置IsRequired(false)
我的列映射。在我的例子中,我正在映射一个数据库视图。
builder.Property(x => x.MyProperty).IsRequired(false);
TA贡献1812条经验 获得超5个赞
解决方案:是的,错误“SqlNullValueException:数据为空。” 当模型将导致问题的字段标记为 [Required] 时,当(表的)列包含 NULL 时引起...使用数字字段可以轻松解决问题,但当字段类型为字符串时问题非常糟糕。 .
想想下面2个类,用了一个分配路线的例子,每条路线都有一个司机,当然每个司机都有1条或多条路线。
public class Route
{
public int id { get; set; }
public string RouteName { get; set; }
[Required] \\==> FIELD CAUSING THE PROBLEM
public string UsuarioId { get; set; }
public virtual Usuario Driver { get; set; }
}
public class Usuario
{
public string Id {get;set;
public string Name { get; set; }
public virtual List<Route> Routes { get; set; } = new List<Route>();
}
你可能猜到了,一个 Route 可以有一个 driver(或者我称之为 Usuario),但是一个 Driver 可以有多个 route,这就构成了一对多的关系,如下所示:
protected override void OnModelCreating(ModelBuilder modelBuilder){
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Usuario>()
.HasMany<Route>(usuario => usuario.Routes)
.WithOne(route => route.Driver)
.HasForeignKey(route => route.UsuarioId)
.OnDelete(DeleteBehavior.SetNull);
}
根据 FluentAPI,删除驱动程序时,行为是将 UsuarioId 字段(在 Routes 模型中)设置为 NULL,但这违反了 [Required] 属性。所以我们将无法删除 Users(或 Drivers)表中的记录。此外,如果我们在数据库中已有数据,在本例中,Routes with NULL UsuarioId,它会立即显示错误。
请记住,重点是:我们希望 [Required] 仅用于验证目的,因为我们可能拥有尚未分配给驱动程序(UserId)的路由,因此在数据库中,它应该被允许为 NULL ,而不是我们的 mvc 形式。
要解决此问题,请将该字段标记为 [required],然后转到您使用 Fluent API 定义关系的 DbContext 类,并指定该列不是必需的,如下所示:
modelBuilder.Entity<Route>()
.Property(p => p.UsuarioId).IsRequired(required: false);
因此该字段现在在注释模式下是必需的,但最终将用于构建数据库的流式 API 不需要该字段。这将解决问题!
- 5 回答
- 0 关注
- 383 浏览
添加回答
举报