1

ASP.NET MVC 4 Web 应用程序、EF 5、SQL Server 2012 Express、Visual Web Developer 2012 Express、代码优先

我有一个地点对象 - 我想为每个地点添加多个标签。

最好的方法是逗号分隔的字符串还是相关对象?

任何设计模式或管理整个事物的方法(添加、查找、与地点关联等)?良好的性能也令人感兴趣。

标记由管理员完成,因此速度/易于实施以牺牲一点易用性为代价是可以接受的。

谢谢。

4

2 回答 2

2

首先,我认为你不需要一个对象来表示一个标签——假设标签只是一个字符串。

您应该做的是将字符串的通用列表属性添加到您的实体,如下所示:

public IList<string> Tags { get; set; }

实体框架会处理得很好。

关于 UI 部分,不要太在意,这几天一切都已经为你实现了,使用 jQuery Tag-It:http ://aehlke.github.io/tag-it/

更新

因为 EntityFramework 很难使用字符串的映射列表,只需为它创建一个简单的类:

public class Tag
{
    public string Name { get; set; }
}

并使用

public IList<Tag> Tags { get; set; }

同样,如果不是因为 EF 的限制(或者如果您使用 nhibernate),我仍然建议映射到字符串列表以避免复杂性(假设速度不是关键)

于 2013-05-20T16:10:25.620 回答
2

无论哪种方式,您都可以真正处理它;它只取决于你想要什么以及你想要完成什么。作为逗号分隔的字符串或IList<string>,它至少是可搜索的,但仅此而已。您也很难对标签进行任何形式的标准化(即不同的地方可能有“Chinese Buffet”、“chinese”、“chinese Buffet”、“chinese-buffet”等)。

最稳健的方法是Tag与 具有 M2M 关系的实际实体Place。这样,您可以通过使名称成为唯一列并执行先发制人的重复数据删除查询(即使用条目:“中文”、“您的意思是'中文'吗?”等)来获得相当程度的规范化。

拥有一个Tag实体还可以让您轻松地进行自动完成查询,因为您将在一个地方查找所有标签或以某个字符开头的标签。用逗号分隔的字符串几乎不可能实现这一点,因为它需要首先聚合所有这些字符串(以及所有不同类型的对象),然后在最终返回列表之前解析出唯一标签。

更新

我不知道任何与 MVC 相关的现有标签项目。Google 应该能够提供帮助或仅在 Visual Studio 中的 NuGet 包管理器中进行搜索。

但是,这很容易自己推出。

public class Tag
{
    public int TagId { get; set; }
    public string Name { get; set; }
    // If your tags will be more freeform (and not necessarily URL compatible)
    public string Slug { get; set; }
}

public class Place
{
    ...
    public virtual ICollection<Tag> Tags
}

这里唯一困难的部分是,为了让 EF 将关系识别为 M2M,关系的双方都需要有一个指向对方的导航属性。你有两个选择:

  1. 继续往两边添加导航属性。因此,Tag您将添加以下行:

    public virtual ICollection<Place> Places
    

    这并没有什么“错误”,如果您希望能够轻松查找特定标签的位置,实际上可能需要这样做。但是,您仍然可以在没有导航属性的情况下获取该信息,即:

    db.Places.Where(m => m.Tags.Contains(someTag))
    
  2. 使用 anEntityTypeConfiguration明确告诉 EF 这是一个 M2M。我通常遵循的模式是在我的实体中创建一个“映射”类:

    public class Place
    {
        ...
    
        public class PlaceMapping : EntityTypeConfiguration<Place>
        {
            public PlaceMapping()
            {
                HasMany(m => m.Tags).WithMany();
            }
        }
    }
    

    然后,在您的 DbContext 中:

    public override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new Place.PlaceMapping());
        // Any other configurations added here the same way
    }
    

    这只是我遵循的模式以保持事物井井有条,EntityTypeConfiguration只要您可以从 DbContext 中引用它,您就可以将其放置在您喜欢的任何位置。

于 2013-05-20T17:16:29.970 回答