c# - 如何解决 SqlNullValueException?

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

我正在尝试查找一个实体,但当 Entity Framework 尝试获取 Null 字段的值时,我收到 SqlNullValueException。

我检查了数据库,所有不可为空的字段都已填充。唯一具有 NULL 值的字段是允许具有 NULL 值的字段。

在其他答案中,我发现我应该从类属性中删除必需的属性或从模型构建器定义中删除 IsRequired 方法,但是我自动生成了这些,并且它们从未有必需的定义。

我的应用程序在 .NET Core 3.1 上运行,我的 EntityFrameworkCore 版本为 2.2.4。即使它构建成功,这也会导致问题吗? 更新现在所有版本都是3.1。

如果不是,还有什么原因造成的?

要查找实体,我使用以下方法:

public static CodeLists FindCodeListById(Guid id)
{
    using (var context = new classificatielocalContext())
    {
        return context.CodeLists.Find(id);
    }
}

但是,我遇到以下异常:

System.Data.SqlTypes.SqlNullValueException

HResult=0x80131931

Message=Data is Null. This method or property cannot be called on Null values.

Source=System.Data.Common

StackTrace:

at System.Data.SqlTypes.SqlGuid.get_Value()

at System.Data.SqlClient.SqlDataReader.GetGuid(Int32 i)

at Microsoft.EntityFrameworkCore.Storage.Internal.TypedRelationalValueBufferFactory.Create(DbDataReader dataReader)

at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable1.Enumerator.BufferlessMoveNext(DbContext _, Boolean buffer)`

at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func3 operation, Func3 verifySucceeded)

at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable1.Enumerator.MoveNext()`

at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable1 source, Boolean& found)`

at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.ResultEnumerable1.GetEnumerator()`

at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.<_TrackEntities>d__172.MoveNext()`

at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.ExceptionInterceptor1.EnumeratorExceptionInterceptor.MoveNext()`

at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable1 source, Boolean& found)`

at System.Linq.Enumerable.First[TSource](IEnumerable1 source)`

at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass15_11.b__0(QueryContext qc)`

at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)

at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)

at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable1 source, Expression1 predicate)

at Microsoft.EntityFrameworkCore.Internal.EntityFinder1.Find(Object[] keyValues)`

at Microsoft.EntityFrameworkCore.Internal.InternalDbSet1.Find(Object[] keyValues)`

at dal.Views.FindCodeListById(Guid id) in ...

at services.CodeListService.GetCodeList(Guid id) in ...

at api.Controllers.CodeListController.Get(Guid id) in ...

at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)

at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)

at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<<InvokeActionMethodAsync>g__Logged|12_1>d.MoveNext()

我正在使用OnModelCreating(ModelBuilder modelBuilder)定义我的实体,但我没有在任何地方定义我的列是必需的。

这是我的模型构建器定义:

modelBuilder.Entity<CodeLists>(entity =>
{
    entity.HasKey(e => e.Id)
        .ForSqlServerIsClustered(false);

    entity.ToTable("code_lists");

    entity.Property(e => e.Id)
        .HasColumnName("id")
        .HasDefaultValueSql("(newsequentialid())");

    entity.Property(e => e.ClassificationId).HasColumnName("classification_id");

    entity.Property(e => e.DescriptionId).HasColumnName("description_id");

    entity.Property(e => e.NameId).HasColumnName("name_id");

    entity.Property(e => e.OwnerId).HasColumnName("owner_id");

    entity.HasOne(d => d.Classification)
        .WithMany(p => p.CodeLists)
        .HasForeignKey(d => d.ClassificationId)
        .OnDelete(DeleteBehavior.ClientSetNull)
        .HasConstraintName("FK__code_list__class__5FB337D6");

    entity.HasOne(d => d.Description)
        .WithMany(p => p.CodeListsDescription)
        .HasForeignKey(d => d.DescriptionId)
        .HasConstraintName("FK__code_list__descr__60A75C0F");

    entity.HasOne(d => d.Name)
        .WithMany(p => p.CodeListsName)
        .HasForeignKey(d => d.NameId)
        .OnDelete(DeleteBehavior.ClientSetNull)
        .HasConstraintName("FK__code_list__name___619B8048");

    entity.HasOne(d => d.Owner)
        .WithMany(p => p.CodeLists)
        .HasForeignKey(d => d.OwnerId)
        .OnDelete(DeleteBehavior.ClientSetNull)
        .HasConstraintName("FK__code_list__owner__628FA481");
});

这是我的 sql 定义

CREATE TABLE [dbo].[code_lists]
(
    [id] UNIQUEIDENTIFIER NOT NULL PRIMARY KEY NONCLUSTERED DEFAULT NEWSEQUENTIALID(),
    [classification_id] UNIQUEIDENTIFIER NULL FOREIGN KEY REFERENCES classifications(id), -- TODO: Should be set to NOT NULL
    [description_id] UNIQUEIDENTIFIER FOREIGN KEY REFERENCES translations(id),
    [name_id] UNIQUEIDENTIFIER NOT NULL FOREIGN KEY REFERENCES translations(id),
    [owner_id] UNIQUEIDENTIFIER NULL FOREIGN KEY REFERENCES users(id), -- TODO: Should be set to NOT NULL
)

更新 更新版本并添加 nuget 包 System.Data.SqlClient 后堆栈跟踪略有更改为:

System.Data.SqlTypes.SqlNullValueException

HResult=0x80131931

Message=Data is Null. This method or property cannot be called on Null values.

Source=Microsoft.Data.SqlClient

StackTrace:

at Microsoft.Data.SqlClient.SqlBuffer.ThrowIfNull()

at Microsoft.Data.SqlClient.SqlBuffer.get_Guid()

at Microsoft.Data.SqlClient.SqlDataReader.GetGuid(Int32 i)

at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable1.Enumerator.MoveNext()`

at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable1 source)`

at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)

at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)

at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable1 source)`

at cbs.classifications.dal.Views.FindCodeListById(Guid id) in ...

at cbs.classifications.services.CodeListService.GetCodeList(Guid id) in ...

at cbs.classifications.api.Controllers.CodeListController.Get(Guid id) in

at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)

at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)

at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<<InvokeActionMethodAsync>g__Logged|12_1>d.MoveNext()

更新了 CodeLists 类

public partial class CodeLists
{
    public CodeLists()
    {
        Levels = new HashSet<Levels>();
        Nodes = new HashSet<Nodes>();
    }

    public Guid Id { get; set; }
    public Guid ClassificationId { get; set; }
    public Guid? DescriptionId { get; set; }
    public Guid NameId { get; set; }
    public Guid OwnerId { get; set; }

    public Classifications Classification { get; set; }
    public Translations Description { get; set; }
    public Translations Name { get; set; }
    public Users Owner { get; set; }
    public ICollection<Levels> Levels { get; set; }
    public ICollection<Nodes> Nodes { get; set; }
}

最佳答案

我的问题是我在类库项目中启用了Nullable 功能。删除 Nullable 节点修复了它。 EFCore 不再抛出错误,并且警告从我的模型中消失。

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

关于c# - 如何解决 SqlNullValueException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59895568/

相关文章:

c# - Xamarin ADFS 库

c# - c# 2.0(BindingList)中泛型缺少协变的解决方案

sql - 使用 NULL 查询性能

mysql - 通过 phpMyAdmin 将数据库转储导出到 MS SQL

c# - EF 5 条件映射

c# - 检索 Entity Framework Core 生成的 SQL

c# - 在 Wpf 和 WinForms 上使用 StreamSocket

c# - 在 Rider 和 Visual Studio 中使用 C# 和 ASP.Net 的 Git 问题

sql - 数据库设计帮助 : Whose kid is this anyway

c# - LINQ to Entities 无法识别 Replace 方法?