![](/img/trans.png)
[英]EF generate System.Data.SqlTypes.SqlNullValueException: Data is Null. This method or property cannot be called on Null values
[英]EF Core 6: Data is Null. This method or property cannot be called on Null values
我正在将我的项目从.Net 4.7
迁移到.Net 6
,所以我也必须迁移我的Entity Framework
。
我已经使用dotnet ef migrations add PortedToEFCore
生成了我的第一个迁移。 根据微软的说法,当我们处理现有数据库时,我们需要从dotnet ef migrations add
中删除添加的迁移记录中的所有Up()
和Down()
。
所以这是我的迁移记录PortedToEFCore
:
public partial class PortedToEFCore : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
}
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
然后我必须修改一些relation table name
以匹配我的旧.Net EF
。
这是我的 model:
public class Account : ObjectMapper
{
[Key]
[Toolbelt.ComponentModel.DataAnnotations.Schema.V5.IndexColumn(IsUnique = true)]
public Guid ID { get; set; } = Guid.NewGuid();
[Required]
[Toolbelt.ComponentModel.DataAnnotations.Schema.V5.IndexColumn(IsUnique = true)]
[StringLength(50)]
[Toolbelt.ComponentModel.DataAnnotations.Schema.V5.IndexColumn("UserStore", 1, IsUnique = true)]
public string UserName { get; set; }
[Required]
public string Password { get; set; }
public string Hash { get; set; }
public ICollection<Role> Roles { get; set; }
[ForeignKey("AccountProfile")]
public Guid? AccountProfileId { get; set; }
public AccountProfile AccountProfile { get; set; }
[ForeignKey("Store")]
[Toolbelt.ComponentModel.DataAnnotations.Schema.V5.IndexColumn("UserStore", 2, IsUnique = true)]
public Guid? StoreId { get; set; }
public Store Store {get;set;}
public ICollection<Access> Access { get; set; }
}
public class Access
{
[Key]
[Toolbelt.ComponentModel.DataAnnotations.Schema.V5.IndexColumn(IsUnique = true)]
public Guid ID { get; set; } = Guid.NewGuid();
public string AccessName { get; set; }
public ICollection<Account> Accounts { get; set; }
}
public class AccountProfile
{
[Key]
[Toolbelt.ComponentModel.DataAnnotations.Schema.V5.IndexColumn(IsUnique = true)]
public Guid ID { get; set; } = Guid.NewGuid();
[Required]
public string Name { get; set; }
public string Description { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string Province { get; set; }
public string PostCode { get; set; }
}
public class Role
{
[Key]
[Toolbelt.ComponentModel.DataAnnotations.Schema.V5.IndexColumn(IsUnique = true)]
public Guid ID { get; set; } = Guid.NewGuid();
[Required]
[StringLength(50)]
[Toolbelt.ComponentModel.DataAnnotations.Schema.V5.IndexColumn(IsUnique = true)]
public string RoleName { get; set; }
public ICollection<Account> Accounts { get; set; }
}
下面的代码是我如何匹配我的relation table name
,默认关系表名是AccountRole
和AccessAccount
所以这段代码是为了匹配表名到RoleAccounts
和AccountAccesses
:
protected override void OnModelCreating(ModelBuilder mb)
{
mb.BuildIndexesFromAnnotations();
base.OnModelCreating(mb);
mb.Entity<Account>()
.HasMany(left => left.Roles)
.WithMany(right => right.Accounts)
.UsingEntity<Dictionary<string, object>>(
"RoleAccounts",
j => j
.HasOne<Role>()
.WithMany()
.HasForeignKey("Role_ID"),
j => j
.HasOne<Account>()
.WithMany()
.HasForeignKey("Account_ID"));
mb.Entity<Account>()
.HasMany(left => left.Access)
.WithMany(right => right.Accounts)
.UsingEntity<Dictionary<string, object>>(
"AccountAccesses",
j => j
.HasOne<Access>()
.WithMany()
.HasForeignKey("Access_ID"),
j => j
.HasOne<Account>()
.WithMany()
.HasForeignKey("Account_ID"));
}
它可以很好地编译,它可以运行。 然后问题是当我尝试检索记录时。
注意这里的ADMIN
账户有NULL
AccountProfileId
和StoreId
。 根据我的 model Account
,这是有效的,但每次我尝试访问ADMIN
帐户时都会出现此错误:
System.Data.SqlTypes.SqlNullValueException:'数据是 Null。 不能对 Null 值调用此方法或属性。
我的示例代码:
var xxx = await db.Accounts.ToListAsync();
此代码引发该错误。
但是,如果我创建并连接一个新的AccountProfile
并将StoreId
分配给Admin
帐户。 可以找回来的。
这是怎么回事? 我的Account
model 指定AccountProfileId
和StoreId
是可选的,为什么这不起作用?
我猜想,不可为空的AccountProfile
和Store
会导致这个问题。 尝试使它们可以为空以检验我的假设。
也就是说,您为什么在问题中描述迁移? 你没有问题,是吗? 我以非常不同的方式进行了类似的转换——但如果你已经有一个与数据库匹配的 model,那可能没关系。 但是您的问题(至少对我而言)非常令人困惑,究竟是什么问题
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.