[英]The entity type 'Uri' requires a primary key to be defined
我引用了一個通用模型,因此無法控制其中的屬性。 假設它看起來像這樣:
public class Message
{
public Guid Id { get; set; }
public string Sender { get; set; }
public Uri Uri { get; set; }
}
其中Uri
是System.Uri
。
在我的上下文中,我然后重寫OnModelCreating
來設置主鍵:
public DbSet<Message> Messages { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Message>()
.HasKey(i => i.Id);
}
然后,我在數據庫初始化程序中運行Initialize
:
public void Initialize()
{
_logger.Information("Ensuring database is created.");
_messageContext.Database.Migrate();
}
但是出現以下錯誤:
The entity type 'Uri' requires a primary key to be defined.
關於如何解決這個問題的任何提示?
編輯:
顯然,這是一個已知問題 。
實體只能包含兩種類型的屬性類型(EF可以使用):
由於Uri
不會映射到原始SQL類型,因此EF會嘗試像對待實體一樣對其進行處理。
實體存儲在單獨的表中。 要將實體存儲在表中,它需要一個唯一的ID。
有一些解決方法。 我建議的方法可以維護Uri
但可以阻止EF嘗試使用它。
第1步-使Uri [NotMapped]
這樣就可以使EF 忽略 Uri屬性,因為它無法正確處理它。
[NotMapped]
public Uri Uri { get; set; }
步驟2-制作EF 應該代替Uri處理的字符串屬性。
字符串值是從(現在是隱藏的) Uri
屬性派生的,但是EF沒有看到。 它僅看到可用的字符串屬性。
public String URL
{
get
{
return this.Uri.AbsoluteUri;
}
set
{
this.Uri = new Uri(value);
}
}
這應該可以解決問題。 在代碼中,您可以直接使用Uri
屬性(就像您已經做過的一樣),但是您已經設置了實體,因此EF可以改為使用URL
字符串屬性。
EF檢索實體並設置其屬性(包括URL
字符串屬性)后,還將隱式創建Uri
屬性,您可以繼續使用它。
對於EF Core 2.0及更早版本,@ Flater的答案是正確的。
對於EF Core 2.1,有更優雅,更通用的方法來解決此問題,而不用轉換代碼污染模型: Value Converters 。
在您的情況下:
public class UriConverter : ValueConverter<Uri, string>
{
public static UriConverter Instance = new UriConverter();
private UriConverter() : base(value => ToUriString(value), value => ToUri(value)) { }
private static string ToUriString (Uri uri) => uri?.ToString();
private static Uri ToUri(string url) => Uri.TryPrase(url, out Uri uri)?uri:null;
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Message>().Property(e => e.Uri)
.HasConversion(UriConverter.Instance);
}
或者對於這個非常簡單的案例,沒有w助手類:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Message>().Property(e => e.Uri)
.HasConversion(
uri => uri?.ToString(),
url => Uri.TryPrase(url, out Uri uri)?uri:null
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.