数据为Null.不能对Null值调用此方法或属性
本文关键字:Null 此方法 值调用 属性 不能 数据 | 更新日期: 2023-09-27 18:27:57
我正在开发一个应用程序,可以从数据库中获取电影信息,还可以添加、更新和删除电影。在数据库中,我有三个表(Movie、Genre和MovieGenre<-存储电影及其类型)。除了一件事之外,一切都很好,那就是一部电影没有任何类型(这应该是可能的)。
以下方法中出现问题,并引发以下异常:数据为Null。不能对Null值调用此方法或属性
原因(当然)是存储过程返回null,因为电影没有任何类型,但我不知道如何防止抛出此异常。正如我所说,应该可以在不存储任何类型信息的情况下存储电影。
方法:
public List<MovieGenre> GetMovieGenrebyMovieID(int movieID) {
using (SqlConnection conn = CreateConnection()) {
try {
SqlCommand cmd = new SqlCommand("dbo.usp_GetMovieGenreByMovieID", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@MovieID", movieID);
List<MovieGenre> movieGenre = new List<MovieGenre>(10);
conn.Open();
using (SqlDataReader reader = cmd.ExecuteReader()) {
int movieGenreIDIndex = reader.GetOrdinal("MovieGenreID");
int movieIDIndex = reader.GetOrdinal("MovieID");
int genreIDIndex = reader.GetOrdinal("GenreID");
while (reader.Read()) {
movieGenre.Add(new MovieGenre {
MovieID = reader.GetInt32(movieIDIndex),
MovieGenreID = reader.GetInt32(movieGenreIDIndex),
GenreID = reader.GetInt32(genreIDIndex)
});
}
}
movieGenre.TrimExcess();
return movieGenre;
}
catch {
throw new ApplicationException();
}
}
}
存储过程:
ALTER PROCEDURE usp_GetMovieGenreByMovieID
@MovieID int
AS
BEGIN
BEGIN TRY
SELECT m.MovieID, g.GenreID, mg.MovieGenreID, g.Genre
FROM Movie AS m
LEFT JOIN MovieGenre AS mg
ON m.MovieId = mg.MovieID
LEFT JOIN Genre AS g
ON mg.GenreID = g.GenreID
WHERE m.MovieID = @MovieID
END TRY
BEGIN CATCH
RAISERROR ('Error while trying to receive genre(s).',16,1)
END CATCH
END
您不应该试图将proc中的null值转换为int,因此在创建MovieGenre实例之前,您需要使用SqlDataReader.IsDBNull
方法检查可为null的字段:
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.isdbnull.aspx
假设GenreID和MovieGenreID是可以为null的int,您可以执行以下操作:
movieGenre.Add(new MovieGenre {
MovieID = reader.GetInt32(movieIDIndex),
MovieGenreID = reader.IsDBNull(movieGenreIDIndex) ? null : reader.GetInt32(movieGenreIDIndex),
GenreID = reader.IsDBNull(genreIDIndex) ? null : reader.GetInt32(genreIDIndex)
});
此错误发生在我在实体框架核心3.1项目中启用C#8可为null的功能之后。
解决方案是将实体属性更改为可为null的对应属性。例如,
更改自:
public class Person {
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
}
收件人:
public class Person {
public int Id { get; set; }
public string Name { get; set; }
public string? Address { get; set; } // change 'Address' to nullable string since it is nullable in database
}
在我的案例中,我使用的是EF Core,问题是该字段在数据库中可以为null,但在ModelCreating中,它是这样要求的:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MyEntity>(entity =>
{
entity.Property(e => e.Details)
.IsRequired()
.HasMaxLength(250);
}
}
我删除了IsRequired(),它运行良好。
几天后更新,得到了同样的问题,一个字符串字段它不允许在数据库中为null。
如下编辑您的选择语句以处理null问题。
SELECT ISNULL(m.MovieID,0) AS MovieID,
ISNULL(g.GenreID,0) AS GenreID,
ISNULL(mg.MovieGenreID,0) AS MovieGenreID,
ISNULL(g.Genre,'') AS Genre
FROM --rest of your query...
我意识到这是旧的,但我刚刚在.net 6中为EF Core遇到了这个问题。
尽管字符串可以为null,实体框架甚至从具有字符串类型的现有表中创建了我的对象,但我必须将字符串列的类型更改为字符串?键入,以便取回数据为null的数据。
错误:
public string Decision { get; set; }
正确:
public string? Decision { get; set; }
我以为我在依赖项注入方面遇到了问题。原来是实体框架核心,这是一个简单的修复。
我在.net5数据优先项目中遇到了这个问题,因为数据库中的一个字段是可以为null的,但在c#实体类中是必需的。通过efcorepowertools扩展重新创建实体后,问题得到了解决。
最简单的答案是用非null值替换null。尝试:
ALTER PROCEDURE usp_GetMovieGenreByMovieID
@MovieID int
AS
BEGIN
BEGIN TRY
SELECT m.MovieID,
coalesce(g.GenreID,0) GenreID,
coalesce(mg.MovieGenreID,0) MovieGenreID,
coalesce(g.Genre, 'Not Applicable') Genre
FROM Movie AS m
LEFT JOIN MovieGenre AS mg
ON m.MovieId = mg.MovieID
LEFT JOIN Genre AS g
ON mg.GenreID = g.GenreID
WHERE m.MovieID = @MovieID
END TRY
BEGIN CATCH
RAISERROR ('Error while trying to receive genre(s).',16,1)
END CATCH
END
如果有人遇到过这个问题,下面是我的案例。
我正在构建WEB Api。在我放置[必需]Attribue之前-https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.requiredattribute?view=net-5.0,我的数据库中有一些NULL值。然后我将这个属性添加到我的模型中,并试图发出GET请求,但";System.InvalidOperationException:数据在序号1处为NULL。不能对NULL值调用此方法。调用之前请使用IsDBNull进行检查"出现。
所以我从数据库中删除了NULL值,之后每个请求都能正常工作据我所知,发生错误是因为EF Core在应用[Required]属性时不允许在数据库中使用NULL值。
我希望这对某人有帮助。
今天我遇到了这个问题。但我的问题已经用另一种方式解决了。如果有一天有人绊倒了,答案就在他们身上。
由于这是一个通用的C#.NET CLI异常
我在一个没有默认值的DB表中添加了一个新的外键。因此,该值被设置为NULL
,因为该列被设置为允许null。我在查询那张表时遇到了这个异常。
作为解决方案,我用适当的值替换了NULL
值(因为它们是外键,所以应该是适当的)。
仅此而已。
谢谢。
对我来说,之所以发生这种情况,是因为在数据库中,我有一个列"XYZ"的值为NULL,但映射到它的模型属性(bool)不可为NULL。
我也遇到了这个问题,对我来说,类中的一个属性被装饰为[Required]
,但表在该列中有空值。有道理。一旦我删除了Required,数据就成功地加载了null值。
BookingQuantity-DB中具有空值的列。但实际DB BookingQuantity不是空列。在一些罕见的情况下,它碰巧进入。在这种情况下,下面的代码抛出错误,即相同的错误(数据为Null。不能对Null值调用此方法或属性)。
totalBookingQuantity += item.InspPoTransactions.Where(x => x.PoId == inspectionPODetail.PoId && x.ProductId == inspectionPODetail.ProductId).Sum(x => Convert.ToInt32(x.BookingQuantity));
此错误可能是由于用户对数据库缺乏权限而导致的。检查用户是否至少具有EXECUTE、SELECT或SHOW DATABASES权限