簡體   English   中英

實體框架將集合屬性映射到一列

[英]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");
        });

編輯2:好的這項工作

        modelBuilder.Entity<FlyerPage>().Map(m =>
        {
            m.Properties(p => p.Keywords);
            m.ToTable("FlyerPageKeywords");
        });

但是,如何將其連接成多對多呢?

根據您的目的(例如,如果FlyerPage關鍵字搜索),可以創建兩個新表,一個用於Keyword (每個記錄都是一個關鍵字),另一個用於映射FlyerPageKeyword之間的關系,其中包含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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM