提问人:Natalie Perret 提问时间:4/28/2019 最后编辑:Natalie Perret 更新时间:10/6/2023 访问量:203873
Entity Framework Core:“SqlNullValueException:数据为 Null”。 如何排除故障?
Entity Framework Core: `SqlNullValueException: Data is Null.` How to troubleshoot?
问:
我在 ASP.NET Core 应用程序和控制器操作中使用 Entity Framework Core,我没有对工作代码或数据库进行任何更改,但我无法判断 Entity Framework Core 执行的查询是什么。
控制器操作:
[HttpGet]
// GET: Administration/Companies
public async Task<ActionResult> Index()
{
var users = await UserManager.Users.ToListAsync();
var companyEditVMs = await DB.Companies
.OrderBy(company => company.CompanyId == 1
? "_" + company.CompanyName
: company.CompanyName
)
Select(a => new CompanyEditVM(HttpContext, a, users.Where(b => b.CompanyId == a.CompanyId)))
.ToListAsync();
return View(companyEditVMs);
}
跟踪
SqlNullValueException: Data is Null. This method or property cannot be called on Null values.
System.Data.SqlClient.SqlBuffer.get_String()
System.Data.SqlClient.SqlDataReader.GetString(int i)
lambda_method(Closure , DbDataReader )
Microsoft.EntityFrameworkCore.Storage.Internal.TypedRelationalValueBufferFactory.Create(DbDataReader dataReader)
Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable<T>+AsyncEnumerator.BufferlessMoveNext(DbContext _, bool buffer, CancellationToken cancellationToken)
Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync<TState, TResult>(TState state, Func<DbContext, TState, CancellationToken, Task<TResult>> operation, Func<DbContext, TState, CancellationToken, Task<ExecutionResult<TResult>>> verifySucceeded, CancellationToken cancellationToken)
Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable<T>+AsyncEnumerator.MoveNext(CancellationToken cancellationToken)
Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider+ExceptionInterceptor<T>+EnumeratorExceptionInterceptor.MoveNext(CancellationToken cancellationToken)
System.Linq.AsyncEnumerable.Aggregate_<TSource, TAccumulate, TResult>(IAsyncEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator, Func<TAccumulate, TResult> resultSelector, CancellationToken cancellationToken) in Aggregate.cs
KYC.Core.Areas.Commercial.Controllers.CompaniesController.Index() in CompaniesController.cs
-
[HttpGet]
// GET: Administration/Companies
public async Task<ActionResult> Index()
{
var users = await UserManager.Users.ToListAsync();
var companyEditVMs = await DB.Companies
.OrderBy(company => company.CompanyId == 1
? "_" + company.CompanyName
: company.CompanyName
)
.Select(a => new CompanyEditVM(HttpContext, a, users.Where(b => b.CompanyId == a.CompanyId)))
.ToListAsync();
lambda_method(Closure , object )
Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable+Awaiter.GetResult()
Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor+TaskOfActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, object controller, object[] arguments)
System.Threading.Tasks.ValueTask<TResult>.get_Result()
我什至试着做.我也有完全相同的例外。var companies = await DB.Companies.ToListAsync()
也许我希望能够获取 EF Core 执行的查询以手动执行此操作,以便我可以尝试找出查询的问题。
我想知道可能会发生什么。特别是因为其他实体(如用户或国家/地区)仍然可以从数据库中获取。
知道如何解决实际的潜在问题吗?
[编辑]
“代码”中唯一实际更改的是 nuget 引用,我基本上升级了几乎所有内容,尽管它没有破坏代码中的引用,但它似乎改变了 EF Core 以某种方式(疯狂猜测)解释数据库的方式。
我确实将我的 git 存储库重置到nuget包更新发生之前的程度,并且一切正常。然后我决定将 EntityFrameworkCore 从 2.0.2 更新到 2.2.4(也尝试过 2.2.0 并最终得到相同的结果),问题再次发生......不确定 2.0.2 和 2.2.0 之间发生了什么变化来触发此异常(但模型相同,只是 EF Core 版本发生了变化)...
这是实体定义,它似乎是使用数据库表/模式中的工具自动生成的:
[Table("T_Companies")]
public partial class Company : INotifyPropertyChanging, INotifyPropertyChanged
{
public override string ToString()
{
return CompanyId + " " + CompanyName;
}
private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(string.Empty);
private int _CompanyId;
private string _CompanyName;
private int _CompanyTypeId;
private int _CountryId;
private string _CompanyVatNumber;
private string _CompanyStreetAddress;
private string _CompanyZipCode;
private string _CompanyCity;
private string _ContactLastName;
private string _ContactFirstName;
private bool? _Active;
private int? _AccountId;
private string _CallbackSalt;
private int? _UserSpaceId;
private string _Login;
private string _Pwd;
private bool _IsTechnicalAccount;
private DateTime? _StatusDate;
private int _BankStatusCode;
private string _PivotalAccount;
private CompanyType _CompanyType;
private Country _Country;
private bool _IsKycIdSent;
#region Extensibility Method Definitions
partial void OnLoaded();
partial void OnCreated();
partial void OnCompanyIdChanging(int value);
partial void OnCompanyIdChanged();
partial void OnCompanyNameChanging(string value);
partial void OnCompanyNameChanged();
partial void OnCompanyCityChanging(string value);
partial void OnCompanyCityChanged();
partial void OnCompanyZipCodeChanging(string value);
partial void OnCompanyZipCodeChanged();
partial void OnContactLastNameChanging(string value);
partial void OnContactLastNameChanged();
partial void OnActiveChanging(bool? value);
partial void OnActiveChanged();
partial void OnCompanyTypeIdChanging(int value);
partial void OnCompanyTypeIdChanged();
partial void OnCountryIdChanging(int value);
partial void OnCountryIdChanged();
partial void OnContactFirstNameChanging(string value);
partial void OnContactFirstNameChanged();
partial void OnCompanyVatNumberChanging(string value);
partial void OnCompanyVatNumberChanged();
partial void OnCompanyStreetAddressChanged();
partial void OnCompanyStreetAddressChanging(string value);
partial void OnAccountIdChanging(int? value);
partial void OnAccountIdChanged();
partial void OnCallbackSaltChanging(string value);
partial void OnCallbackSaltChanged();
partial void OnUserSpaceIdChanging(int? value);
partial void OnUserSpaceIdChanged();
partial void OnLoginChanging(string value);
partial void OnLoginChanged();
partial void OnPwdChanging(string value);
partial void OnPwdChanged();
partial void OnIsTechnicalAccountChanging(bool value);
partial void OnIsTechnicalAccountChanged();
partial void OnStatusDateChanging(DateTime? value);
partial void OnStatusDateChanged();
partial void OnBankStatusCodeChanging(int value);
partial void OnBankStatusCodeChanged();
partial void OnPivotalAccountChanging(string value);
partial void OnPivotalAccountChanged();
partial void OnIsKycIdSentChanging(bool value);
partial void OnIsKycIdSentChanged();
#endregion
public Company()
{
OnCreated();
}
[Key, Column("CompanyId"), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int CompanyId
{
get => _CompanyId;
set
{
if (_CompanyId != value)
{
OnCompanyIdChanging(value);
SendPropertyChanging();
_CompanyId = value;
SendPropertyChanged("CompanyId");
OnCompanyIdChanged();
}
}
}
[DataType(DataType.Text), StringLength(1024), Column("CompanyName"), Required]
public string CompanyName
{
get => _CompanyName;
set
{
if (_CompanyName != value)
{
OnCompanyNameChanging(value);
SendPropertyChanging();
_CompanyName = value;
SendPropertyChanged("CompanyName");
OnCompanyNameChanged();
}
}
}
[Column("CompanyTypeId"), Required]
public int CompanyTypeId
{
get => _CompanyTypeId;
set
{
if (_CompanyTypeId != value)
{
OnCompanyTypeIdChanging(value);
SendPropertyChanging();
_CompanyTypeId = value;
SendPropertyChanged("CompanyTypeId");
OnCompanyTypeIdChanged();
}
}
}
[Column("CountryId"), Required]
public int CountryId
{
get => _CountryId;
set
{
if (CountryId != value)
{
OnCountryIdChanging(value);
SendPropertyChanging();
_CountryId = value;
SendPropertyChanged("CountryId");
OnCountryIdChanged();
}
}
}
[DataType(DataType.Text), StringLength(100), Column("CompanyCity"), Required]
public string CompanyCity
{
get => _CompanyCity;
set
{
if (_CompanyCity != value)
{
OnCompanyCityChanging(value);
SendPropertyChanging();
_CompanyCity = value;
SendPropertyChanged("CompanyCity");
OnCompanyCityChanged();
}
}
}
[DataType(DataType.Text), StringLength(100), Column("CompanyStreetAddress"), Required]
public string CompanyStreetAddress
{
get => _CompanyStreetAddress;
set
{
if (_CompanyStreetAddress != value)
{
OnCompanyStreetAddressChanging(value);
SendPropertyChanging();
_CompanyStreetAddress = value;
SendPropertyChanged("CompanyStreetAddress");
OnCompanyStreetAddressChanged();
}
}
}
[DataType(DataType.Text), StringLength(30), Column("CompanyVatNumber"), Required]
public string CompanyVatNumber
{
get => _CompanyVatNumber;
set
{
if (_CompanyVatNumber != value)
{
OnCompanyVatNumberChanging(value);
SendPropertyChanging();
_CompanyVatNumber = value;
SendPropertyChanged("CompanyVatNumber");
OnCompanyVatNumberChanged();
}
}
}
[DataType(DataType.Text), StringLength(10), Column("CompanyZipCode"), Required]
public string CompanyZipCode
{
get => _CompanyZipCode;
set
{
if (_CompanyZipCode != value)
{
OnCompanyZipCodeChanging(value);
SendPropertyChanging();
_CompanyZipCode = value;
SendPropertyChanged("CompanyZipCode");
OnCompanyZipCodeChanged();
}
}
}
[DataType(DataType.Text), StringLength(1024), Column("ContactLastName"), Required]
public string ContactLastName
{
get => _ContactLastName;
set
{
if (_ContactLastName != value)
{
OnContactLastNameChanging(value);
SendPropertyChanging();
_ContactLastName = value;
SendPropertyChanged("ContactLastName");
OnContactLastNameChanged();
}
}
}
[DataType(DataType.Text), StringLength(1024), Column("ContactFirstName"), Required]
public string ContactFirstName
{
get => _ContactFirstName;
set
{
if (_ContactFirstName != value)
{
OnContactFirstNameChanging(value);
SendPropertyChanging();
_ContactFirstName = value;
SendPropertyChanged("ContactFirstName");
OnContactFirstNameChanged();
}
}
}
[Column("Active"), Required]
public bool? Active
{
get => _Active;
set
{
if (_Active != value)
{
OnActiveChanging(value);
SendPropertyChanging();
_Active = value;
SendPropertyChanged("Active");
OnActiveChanged();
}
}
}
[Column("AccountId")]
public int? AccountId
{
get => _AccountId;
set
{
if (_AccountId != value)
{
OnAccountIdChanging(value);
SendPropertyChanging();
_AccountId = value;
SendPropertyChanged("AccountId");
OnAccountIdChanged();
}
}
}
[DataType(DataType.Text), StringLength(1024), Column("CallbackSalt")]
public string CallbackSalt
{
get => _CallbackSalt;
set
{
if (_CallbackSalt != value)
{
OnCallbackSaltChanging(value);
SendPropertyChanging();
_CallbackSalt = value;
SendPropertyChanged("CallbackSalt");
OnCallbackSaltChanged();
}
}
}
[Column("UserSpaceId")]
public int? UserSpaceId
{
get => _UserSpaceId;
set
{
if (_UserSpaceId != value)
{
OnUserSpaceIdChanging(value);
SendPropertyChanging();
_UserSpaceId = value;
SendPropertyChanged("UserSpaceId");
OnUserSpaceIdChanged();
}
}
}
[DataType(DataType.Text), StringLength(1024), Column("Login")]
public string Login
{
get => _Login;
set
{
if (_Login != value)
{
OnLoginChanging(value);
SendPropertyChanging();
_Login = value;
SendPropertyChanged("Login");
OnLoginChanged();
}
}
}
[DataType(DataType.Text), StringLength(1024), Column("Pwd")]
public string Pwd
{
get => _Pwd;
set
{
if (_Pwd != value)
{
OnPwdChanging(value);
SendPropertyChanging();
_Pwd = value;
SendPropertyChanged("Pwd");
OnPwdChanged();
}
}
}
[Column("IsTechnicalAccount"), Required]
public bool IsTechnicalAccount
{
get => _IsTechnicalAccount;
set
{
if (_IsTechnicalAccount != value)
{
OnIsTechnicalAccountChanging(value);
SendPropertyChanging();
_IsTechnicalAccount = value;
SendPropertyChanged("IsTechnicalAccount");
OnIsTechnicalAccountChanged();
}
}
}
[DataType(DataType.DateTime), Column("StatusDate")]
public DateTime? StatusDate
{
get => _StatusDate;
set
{
if (_StatusDate != value)
{
OnStatusDateChanging(value);
SendPropertyChanging();
_StatusDate = value;
SendPropertyChanged("StatusDate");
OnStatusDateChanged();
}
}
}
[Column("BankStatusCode")]
public int BankStatusCode
{
get => _BankStatusCode;
set
{
if (_BankStatusCode != value)
{
OnBankStatusCodeChanging(value);
SendPropertyChanging();
_BankStatusCode = value;
SendPropertyChanged("BankStatusCode");
OnBankStatusCodeChanged();
}
}
}
[DataType(DataType.Text), StringLength(255), Column("PivotalAccount")]
public string PivotalAccount
{
get => _PivotalAccount;
set
{
if (_PivotalAccount != value)
{
OnPivotalAccountChanging(value);
SendPropertyChanging();
_PivotalAccount = value;
SendPropertyChanged("PivotalAccount");
OnPivotalAccountChanged();
}
}
}
public List<Resultat> Resultats { get; set; }
public CompanyType CompanyType
{
get => _CompanyType;
set
{
var previousValue = _CompanyType;
if (previousValue != value)
{
SendPropertyChanging();
_CompanyType = value;
if (value != null)
{
CompanyTypeId = value.CompanyTypeId;
}
else
{
_CompanyTypeId = default;
}
SendPropertyChanged("CompanyType");
}
}
}
public Country Country
{
get => _Country;
set
{
var previousValue = _Country;
if (previousValue != value)
{
SendPropertyChanging();
_Country = value;
_CountryId = value?.CountryId ?? default;
SendPropertyChanged("Country");
}
}
}
[Column("IsKycIdSent"), Required]
public bool IsKycIdSent
{
get => _IsKycIdSent;
set
{
if (_IsKycIdSent != value)
{
OnIsKycIdSentChanging(value);
SendPropertyChanging();
_IsKycIdSent = value;
SendPropertyChanged("IsKycIdSent");
OnIsKycIdSentChanged();
}
}
}
public event PropertyChangingEventHandler PropertyChanging;
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void SendPropertyChanging()
{
PropertyChanging?.Invoke(this, emptyChangingEventArgs);
}
protected virtual void SendPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private void Attach_Resultats(Resultat entity)
{
SendPropertyChanging();
entity.Company = this;
}
private void Detach_Resultats(Resultat entity)
{
SendPropertyChanging();
entity.Company = null;
}
}
以及相关的表创建脚本:
create table T_Companies
(
CompanyId int identity (10) identity
primary key nonclustered,
CompanyName varchar(1024) not null,
CompanyTypeId int not null
constraint FK_Company_CompanyType
references T_CompanyTypes,
CountryId int not null
constraint FK_Company_Country
references T_Countries,
Active bit not null,
AccountId int,
CallbackSalt varchar(1024),
UserSpaceId int,
Login varchar(1024),
Pwd varchar(1024),
StatusDate datetime(23, 3),
BankStatusCode int not null,
PivotalAccount varchar(255),
IsTechnicalAccount bit not null,
CompanyStreetAddress varchar(256),
CompanyCity varchar(256),
CompanyZipCode varchar(10),
CompanyVatNumber varchar(30),
ContactFirstName varchar(20),
ContactLastName varchar(20),
IsKycIdSent bit not null
)
go
[编辑 2]
对于完全相同的模型,这(在 nuget 引用的项目文件中)有效
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.1.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.1.8" />
而那些,不:
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.2.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.2.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.2.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.1.8" />
答:
更新:
我之前所说的所有内容仍然适用,由于后来的 EF Core 可空性规则更改,只是有其他方法出错(最明显的是启用 NRT 的项目内的属性,这些属性现在默认被视为必需的,这与它们在非启用 NRT 的上下文中被视为完全相反)。string
我想在这里添加的是检测哪个列/属性导致问题的机制。
我有点忘记了哪个确切的 EF Core 版本添加了此类功能,但在最近的 EF Core 版本中,您可以使用 EnableDetailedErrors 方法打开详细错误日志记录,然后而不是 OP 异常(它仍然存在,但作为新的内部),您将收到类似于以下内容的消息InvalidOperationException
读取属性“{EntityName}”的数据库值时出错。{PropertyName}'。预期类型为“System.String”,但实际值为 null。
其中有问题的属性。{EntityName}.{PropertyName}
原文:
错误消息指示 EF Core 正在尝试读取所需属性的值,即在数据库中不应具有值的属性,而是基础数据读取器在某些记录中报告该属性的值。string
null
null
查看实体模型和相应的数据库表,可以看到许多属性 -> 列存在明显差异。、 、 、 、 - 所有这些都在模型中标记为,但在表中没有相应的约束。string
varchar
CompanyStreetAddress
CompanyCity
CompanyZipCode
CompanyVatNumber
ContactFirstName
ContactLastName
[Required]
not null
因此,问题是由这些列中的一列或多列引起的。
您需要修复这种差异 - 可能是通过删除属性,因为现有数据中的约束已经被破坏。
如果使用的是 Database First 模型,则应在生成的 OnModelCreating 中删除,或者使用 EF Core Tools 重新生成模式。[Required]
builder.Property(x => x.MyProperty).IsRequired();
它在某些较旧的 EF Core 版本中“工作”这一事实并不重要 - 这是不正确的映射,因此应该修复。从技术上讲,它不应该从一开始就起作用。但请记住,EF Core 仍处于积极开发阶段,并且有许多 bug,这些 bug 将在下一个版本中修复。很可能在“工作”和“非工作”EF Core 版本之间进行了一些代码更改,从而修复了以前的错误行为。
评论
如果尝试从数据库中读取一些可为 null 的数据,但类型不可为 null,则可能会出现此错误。
如果在数据库中为 null,并且您有以下实体: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>
int?
public class MyEntity
{
public int Id { get; set; }
public int? MyInt { get; set; }
}
注意:这不是对原始问题的回答,而是对标题中问题的回答。
评论
public bool Isgstvailable { get; set; }
检查 SQL 视图或表中的位列。如果它返回 null ,则 C# 读取器无法读取并引发 null ref 异常。
商品及服务税(GST)的情况。Isgstvailable 为 null 然后强制转换(0 作为位) 否则消费税。Isgstvailable end 为 Isgstvailable
评论
如果从 C# 8 启用最新的 Nullable 功能,也会出现此类异常。
EF Core,至少目前,它与 C# 8 可为 null 的类型不完全兼容。 因此,例如,假设您为项目启用了 Nullable 功能,如果您有如下类型:
public class MyEntity
{
public string MyProperty { get; set; }
}
即使该属性未使用 [Required] 属性标记,EF 核心也会引发此类异常,因为它要求数据库中的值不为 null(即,它不会使用 IsDbNull 测试列值)。
有关如何在 EF Core 中处理可为 null 的引用类型的详细信息,请查看: https://learn.microsoft.com/en-us/ef/core/miscellaneous/nullable-reference-types
评论
为了解决类似的异常问题,我必须明确地放置我的列映射。就我而言,我正在映射数据库视图。Data is Null
IsRequired(false)
builder.Property(x => x.MyProperty).IsRequired(false);
评论
解决方案:是的,当模型将导致问题的字段标记为 [必需] 时,当(表的)列包含 NULL 时,会导致错误“SqlNullValueException:数据为 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>();
}
正如您可能猜到的那样,路由可以有一个驱动程序(或我称之为 Usuario),但一个驱动程序可以有多个路由,这形成了一对多关系,如下所示:
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 字段(在路由模型中)设置为 NULL,但这违反了 [Required] 属性。因此,我们将无法删除“用户”(或“驱动程序”)表中的记录。此外,如果我们数据库中已经有数据,在本例中为 NULL UsuarioId 的路由,它将立即显示错误。
请记住,关键是:我们希望 [Required] 仅用于验证目的,因为我们可能拥有尚未分配给驱动程序 (UserId) 的路由,因此在数据库中,它应该被允许为 NULL,而不是在我们的 mvc 表单中。
若要解决此问题,请将该字段标记为 [必填],然后转到 DbContext 类,在该类中,您使用 Fluent API 定义了关系,并指定该列不是必需的,如下所示:
modelBuilder.Entity<Route>()
.Property(p => p.UsuarioId).IsRequired(required: false);
因此,该字段现在在注释架构下是必需的,但最终将用于构建数据库的 Fluent API 不需要该字段。这将解决问题!
评论
不是 OP 情况,但这也可能与关系中的主键<>外键配置倒置有关。
例如:
entity
.HasOne(e => e.Principal)
.WithOne(e => e.Dependent)
.HasForeignKey<Principal>(e => e.Key) <- This should be the dependent entity
.HasPrincipalKey<Dependent>(e => e.Key); <- This should be the principal entity
而不是
entity
.HasOne(e => e.Principal)
.WithOne(e => e.Dependent)
.HasForeignKey<Dependent>(e => e.Key)
.HasPrincipalKey<Principal>(e => e.Key);
只是想在这里发布这个;
这里的解决方案很棒,但在我的情况下不起作用。我使用的是 SQL 视图而不是表,并且我的字段在模型中没有标记 [Required]。
经过一些故障排除,我发现问题来自我的整数列为 null。我只是将模型中的 int 列更改为字符串(我需要此信息仅用于显示目的),它就成功了。
从
public int BatchId { get; set; }
自
public string BatchId { get; set; }
我希望这对某人有所帮助。感谢以上所有回答!
评论
[使用 isRequired()][1] 我通过在数据库上下文中定义表的所有属性(由 scafford 生成)来解决我的问题,无论是否需要。
从模型中删除 [必需]。 并使用: < cshtml 中的输入 data-val=“true” data-val-required=“write a message for validation” >
如果要忽略这些值,则添加 DefaultIfEmpty() 有效。
_context.<YourDbSet>.DefaultIfEmpty().ToListAsync();
在这种情况下:
var companyEditVMs = await DB.Companies
.OrderBy(company => company.CompanyId == 1
? "_" + company.CompanyName
: company.CompanyName
)
Select(a => new CompanyEditVM(..--..)).DefaultIfEmpty()
.ToListAsync();
评论
就我而言,这是由于我将数据库中的列从不可空更改为可空,然后忘记了我需要再次重新运行 Scaffold-DbContext 以便更新实体类。我正在使用数据库优先的 Entity Framework Core。
我通过添加
modelBuilder.Entity<EntityName>().HasNoKey();
to 方法DbContext
protected override void OnModelCreating(ModelBuilder modelBuilder)
因为我的存储过程为属性返回。null
Id
我只需要在模型上放置 (int?) 的 c# 属性并且工作正常,因为数据库列允许 null。
评论
我在视图上遇到了同样的问题。SQL/SSMS 的最大问题是视图不会刷新,因此 EF 基架不会获取更改。
此代码将刷新视图元数据,使 EF 能够在基架时查看 NULL/NOT NULL 属性更改等小更改。
-- Loop and refresh all views.
DECLARE @ViewName VARCHAR(100), @SchemaName VARCHAR(20);
DECLARE [views_cursor] CURSOR FOR
SELECT v.[name] AS ViewName, s.[name] AS SchemaName
FROM [sys].[views] v INNER JOIN [sys].[schemas] s ON s.[schema_id] = v.[schema_id]
WHERE v.[type] = 'V'
ORDER BY SchemaName, ViewName;
OPEN [views_cursor];
FETCH NEXT FROM [views_cursor]
INTO @ViewName, @SchemaName;
-- Check @@FETCH_STATUS to see if there are any more rows to fetch.
WHILE @@FETCH_STATUS = 0
BEGIN
BEGIN TRY
DECLARE @FullName VARCHAR(120) = @SchemaName + '.' + @ViewName;
PRINT 'Refreshing: ' + @FullName
EXEC sp_refreshview @FullName
END TRY
BEGIN CATCH
PRINT 'Error: ' + @FullName
END CATCH
FETCH NEXT FROM [views_cursor]
INTO @ViewName, @SchemaName;
END
CLOSE [views_cursor];
DEALLOCATE [views_cursor];
GO
我知道这是一个老问题,但以防万一有人还在看。从
public string RRN { get; set; }
自
public string? RRN { get; set; }
或者在 cproj 文件中禁用可为 null 的
<Nullable>disable</Nullable>
评论
await DB.Companies.ToListAsync()