[英]Entity Framework map collection property to one column
我有模特:
public class FlyerPage
{
public Guid Id { get; set; }
public string Picture { get; set; }
public int? Page { get; set; }
public string Text { get; set; }
public ICollection<string> Keywords { get; set; }
public Guid FlyerId { get; set; }
public virtual Flyer Flyer { get; set; }
}
我想將Keywords
映射到FlyerPage
表中的一列。 我認為將其拆分為以逗號分隔的值的最佳方法是
"one", "two", "three".
怎么做? 通過FluentAPI。
The type 'ICollection<string>' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method
modelBuilder.Entity<FlyerPage>().Map(m =>
{
m.Property(p => p.Keywords);
m.ToTable("Keyword", "Flyers.Page");
});
modelBuilder.Entity<FlyerPage>().Map(m =>
{
m.Properties(p => p.Keywords);
m.ToTable("FlyerPageKeywords");
});
但是,如何將其連接成多對多呢?
根據您的目的(例如,如果FlyerPage
關鍵字搜索),可以創建兩個新表,一個用於Keyword
(每個記錄都是一個關鍵字),另一個用於映射FlyerPage
和Keyword
之間的關系,其中包含FlyerPage
的ID和Keyword
作為外鍵。
這樣,通過關鍵字搜索可能會更加高效(即使使用所有JOIN),您可以避免存儲重復的值,並且很可能與您的應用程序邏輯更加接近。
您將最終得到兩個表(還有一個表將自動生成):
public class FlyerPage
{
public Guid Id { get; set; }
public string Picture { get; set; }
public int? Page { get; set; }
public string Text { get; set; }
public ICollection<Keyword> Keywords { get; set; }
public Guid FlyerId { get; set; }
public virtual Flyer Flyer { get; set; }
}
public class Keyword
{
public Guid Id { get; set; }
public string Value { get; set; }
public virtual ICollection<FlyerPage> FlyerPages { get; set; }
}
然后使用FluentAPI進行多對多映射:
modelBuilder.Entity<FlyerPage>()
.HasMany(t => t.Keywords)
.WithMany(t => t.FlyerPages)
.Map(m =>
{
m.ToTable("FlyerPageKeywords");
m.MapLeftKey("FlyerPageID");
m.MapRightKey("KeywordID");
});
我認為它將解決您的問題。 我在FluentAPI中不是完全“流利的”,您可能必須將類的構造函數中的集合初始化為空集合。
另外,根據文檔 ,使關系成為雙向關系的原因(即,將ICollection<FlyerPage>
存儲在您的Keyword
對象中)是:
按照慣例,Code First始終將單向關系解釋為一對多。
如果我正確理解您的要求,那么您想做一個不好的數據庫實踐,以逗號分隔的集合添加到記錄的一列。 我不明白您要按照指定的方式完成什么。 無論如何要實現您的要求。
//這確實是一個壞習慣。 我強烈建議您選擇SándorMátyásMárton的解決方案,這是完成實際用例的最佳實踐。
您需要使用其他實體
public class FlyerPage
{
public Guid Id { get; set; }
public string Picture { get; set; }
public int? Page { get; set; }
public string Text { get; set; }
public string KeywordsCollection { get; set; }
public Guid FlyerId { get; set; }
public virtual Flyer Flyer { get; set; }
}
在這里你可以設置
KeywordsCollection = string.Join(",", flierPage.Keywords);
//flierPage is the viewmodel object and flierPage.Keywords is the collection
//you got from the viewmodel
如果確實必須將標准化數據存儲在單個字段中,則可以通過如下修改類來實現此目的:
public class FlyerPage
{
public ICollection<string> Keywords
{
get
{
return _keywords.Split(',');
}
set
{
_keywords = string.Join(",", value);
}
}
private string _keywords;
}
然后,在流暢的映射中,將“ Keywords
屬性設置為忽略並映射_keywords
字段。
創建關鍵字的合並列表。
public class FlyerPage
{
.....
public string JoinedKeywords
{
get
{
return String.Join(",", this.Keywords);
}
}
public ICollection<string> Keywords {get; set;}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.