我一直在開發 C# ASP.NET Core 應用程式,目前正在使用 SQL Server 物件資源管理器開發資料庫。我想顯示某些硬編碼資料作為測驗,但是當我嘗試運行該頁面時,出現此錯誤
System.InvalidOperationException: '物體型別 'recent_health_issue' 需要定義一個主鍵。如果您打算使用無鍵物體型別,請在“OnModelCreating”中呼叫“HasNoKey”
我的主鍵已經定義好了,顯示頁面正常作業,沒有那行錯誤代碼,所以我在這里不確定。
我的資料庫:

模型類:
public class recent_health_issue
{
[Required, MinLength(3, ErrorMessage = "Enter at least 3 characters"),
MaxLength(5)]
public string recent_id { get; set; }
[Required, MaxLength(25)]
public string recent_name { get; set; }
[Required, EmailAddress]
public string recent_email { get; set; }
[Required]
public string recent_description { get; set; }
}
我的DbContext:
public class RecentHealthIssueDBContext : DbContext
{
private readonly IConfiguration _config;
public RecentHealthIssueDBContext(IConfiguration configuration)
{
_config = configuration;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
string connectionString = _config.GetConnectionString("MyConn");
optionsBuilder.UseSqlServer(connectionString);
}
public DbSet<recent_health_issue> HealthIssues { get; set; }
}
我的控制器(發生錯誤的地方):
public class RecentHealthController
{
private RecentHealthIssueDBContext _context;
public RecentHealthController(RecentHealthIssueDBContext context)
{
_context = context;
}
public List<recent_health_issue> getAllRecentHealthIssues()
{
List<recent_health_issue> AllRecentHealth = new List<recent_health_issue>();
// error occured here
AllRecentHealth = _context.HealthIssues.ToList();
return AllRecentHealth;
}
public recent_health_issue getRecentHealthIssueById(String id)
{
recent_health_issue RecentHealthIssue = new recent_health_issue();
return RecentHealthIssue;
}
}
uj5u.com熱心網友回復:
錯誤訊息說您需要為表定義主鍵:
[Key]
[Required, MinLength(3, ErrorMessage = "Enter at least 3 characters"),
MaxLength(5)]
public string recent_id { get; set; }
還嘗試重命名DbSet您的屬性DbContext以匹配資料庫表名稱,而RecentHealthIssues不是HealthIssues:
public DbSet<recent_health_issue> RecentHealthIssues { get; set; }
uj5u.com熱心網友回復:
為了澄清,根據您的問題,您首先進行資料庫開發。
這意味著您的模型和您的資料庫需要完全匹配,因此如果存在任何差異,那么在大多數情況下將無法正常作業。
Entity Framework 期望屬性使用 Pascal Case,如果它找到一個名為“Id”或包含“Id”的屬性,那么它將假定這是關鍵。
如果您不遵循 pascal case(這是 C# 標準),或者不使用包含字母“Id”的屬性,那么您必須使用 [Key] 資料注釋。
當您首先使用資料庫時,您為 SQL 表選擇了蛇形大小寫,這意味著您需要將名稱與 C# 對齊,而不破壞編碼約定并允許 EF 完成它的作業。
此外,查看您的代碼和您在做什么,因為您使用 snake_case 來定義資料庫中的名稱,那么您應該使用表/列名稱的資料注釋,而不是將您的屬性名稱更改為對齊,如定義在這里:https : //docs.microsoft.com/en-us/ef/ef6/modeling/code-first/data-annotations#table-and-column
供您參考,EF 需要 C# 中的 Pascal 大小寫,因此它可以實作自動化(這就是您應該使用它的原因)
public long Id {get;set;} //ef will recognise this as a Key
public long HelloCheekyThisIsMyId {get;set;} //ef will recognise this as a Key
[Key] //ef will be told this is a key
public long product_identity { get; set; }
所以你的模型應該是這樣的:
[Table("recent_health_issue")]
public class RecentHealthIssue
{
[Key] //this shouldn't be needed but it's good for readability
[Required, MinLength(3, ErrorMessage = "Enter at least 3 characters"), MaxLength(5)]
[Column("recent_id")]
public string RecentId { get; set; }
[Required, MaxLength(25)]
[Column("recent_name")]
public string RecentName { get; set; }
[Required, EmailAddress]
[Column("recent_email")]
public string RecentEmail { get; set; }
[Required]
[Column("recent_description")]
public string RecentDescription { get; set; }
}
如檔案中所定義:“不要將 Column 的 TypeName 屬性與 DataType DataAnnotation 混淆。DataType 是用于 UI 的注釋,被 Code First 忽略。”
你的背景關系是這樣的:
public class RecentHealthIssueDBContext : DbContext
{
private readonly IConfiguration _config;
public RecentHealthIssueDBContext(IConfiguration configuration)
{
_config = configuration;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
string connectionString = _config.GetConnectionString("MyConn");
optionsBuilder.UseSqlServer(connectionString);
}
public DbSet<RecentHealthIssue> HealthIssues { get; set; }
}
你的控制器應該是這樣的:
public class RecentHealthController
{
private RecentHealthIssueDBContext _context;
public RecentHealthController(RecentHealthIssueDBContext context)
{
_context = context;
}
//This should be PascalCase (GetAllRecentHealthIssues)
public List<recent_health_issue> getAllRecentHealthIssues()
{
List<RecentHealthIssue> allRecentHealth = new List<RecentHealthIssue>();
allRecentHealth = _context.HealthIssues.ToList(); //error occured here
return allRecentHealth;
}
//This should be PascalCase (GetRecentHealthIssuesById)
public recent_health_issue getRecentHealthIssueById(String id)
{
//return recent health issues using an Id
}
}
另外我會推薦一些防御性編程,它會在未來為你省去麻煩。(空檢查、try/catch 塊等)
這是 C# 編碼約定:https : //docs.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions
您可以在此處找到有關可用注釋的更多資訊:https : //docs.microsoft.com/en-us/ef/ef6/modeling/code-first/data-annotations#key
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/387427.html
