我如何解决SqlNullValueException?

问题描述 投票:5回答:1

[我正在尝试找到一个实体,但是当实体框架试图获取Null字段的值时,我收到SqlNullValueException。

我已在数据库中签入,所有不可为空的字段均已填写。具有NULL值的唯一字段是允许具有该值的字段。

在其他答案中,我发现我应该从类属性中删除必需的属性,或者从modelbuilder定义中删除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 =数据为空。无法在Null值上调用此方法或属性。

Source = System.Data.Common

StackTrace:

System.Data.SqlTypes.SqlGuid.get_Value()

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

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

Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable 1.Enumerator.BufferlessMoveNext(DbContext _,Boolean buffer)`

Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func 3操作,功能3 verifySucceeded)

Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable 1.Enumerator.MoveNext()`

System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable 1源,布尔值&找到)

Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.ResultEnumerable 1.GetEnumerator()`

Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.<_TrackEntities>d__17 2.MoveNext()`

Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.ExceptionInterceptor 1.EnumeratorExceptionInterceptor.MoveNext()`

System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable 1源,布尔值&找到)

System.Linq.Enumerable.First[TSource](IEnumerable 1来源)`

Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass15_1 1.b__0(QueryContext qc)`

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

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

System.Linq.Queryable.FirstOrDefault[TSource](IQueryable 1源处,表达式1 predicate)

Microsoft.EntityFrameworkCore.Internal.EntityFinder 1.Find(Object [] keyValues)`

Microsoft.EntityFrameworkCore.Internal.InternalDbSet 1.Find(Object [] keyValues)`

dal.Views.FindCodeListById(Guid id)在...

services.CodeListService.GetCodeList(Guid id)在...

api.Controllers.CodeListController.Get(Guid id)在...

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

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

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 =数据为空。无法在Null值上调用此方法或属性。

Source = Microsoft.Data.SqlClient

StackTrace:

Microsoft.Data.SqlClient.SqlBuffer.ThrowIfNull()

Microsoft.Data.SqlClient.SqlBuffer.get_Guid()

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

Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable 1.Enumerator.MoveNext()`

System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable 1来源)`

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

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

System.Linq.Queryable.FirstOrDefault[TSource](IQueryable 1来源)`

cbs.classifications.dal.Views.FindCodeListById(Guid id)在...

cbs.classifications.services.CodeListService.GetCodeList(Guid id)在...

cbs.classifications.api.Controllers.CodeListController.Get(Guid id)中的

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

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

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; }
}
c# sql-server entity-framework .net-core entity-framework-core
1个回答
0
投票

您必须使用如下所示的Nullable数据类型标记所有可为空的CodeLists属性:

public class CodeLists
{
    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; }

}

[ClassificationIdOwnerId在您的CodeLists类实现中不可为空,但在Db中可为空

© www.soinside.com 2019 - 2024. All rights reserved.