我有模特:
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");
});
但是如何将它连接到很多?
答案 0 :(得分:2)
根据您的目的(例如,如果您想按关键字搜索),您可以创建两个新表,一个用于Keyword
s(其中每个记录都是关键字),另一个用于映射关系一个FlyerPage
和一个Keyword
,其中包含FlyerPage
和Keyword
的ID作为外键。
通过关键字搜索可能会更有效率(即使使用所有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中完全“流利”,你可能必须将类的构造函数中的集合初始化为空集合。
此外,根据documentation,根据Plunkr,将关系设置为双向(即在ICollection<FlyerPage>
对象中存储Keyword
)的原因是:
按照惯例,Code First总是将单向关系解释为一对多。
答案 1 :(得分:2)
如果我理解你的要求正确,你想做一个糟糕的数据库练习,将逗号分隔的争论添加到记录的一列。 我不明白你想要以指定的方式完成什么。 无论如何要实现你的要求。
//这真是一个不好的做法。我强烈建议您选择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
答案 2 :(得分:0)
如果你真的必须将规范化数据存储在一个字段中,那么你可以通过修改你的类来实现这一点:
public class FlyerPage
{
public ICollection<string> Keywords
{
get
{
return _keywords.Split(',');
}
set
{
_keywords = string.Join(",", value);
}
}
private string _keywords;
}
然后在您的流畅映射中,将Keywords
属性设置为忽略并映射_keywords
字段。
答案 3 :(得分:0)
创建关联关键字列表。
public class FlyerPage
{
.....
public string JoinedKeywords
{
get
{
return String.Join(",", this.Keywords);
}
}
public ICollection<string> Keywords {get; set;}
}