【问题标题】:EF - Code First: Problem saving values in a many-to-many relationshipEF - Code First:在多对多关系中保存值的问题
【发布时间】:2011-08-14 13:02:13
【问题描述】:

我正在尝试将标记系统添加到基于 MVC3 构建的 Web 应用程序中,使用 EF Code First 进行数据访问。基础非常简单。我有可以有 1 个或多个标签的项目、公司和人员。我不想单独保存每个实体的标签,因此标签类有 3 个 ICollections:人员、公司和项目。每个实体都有一个标签的ICollection。看下面的代码

public class Project 
{
    public int ID { get; set; }
    public virtual ICollection<Tag> Tags { get; set; }
}

public class Person
{
    public int ID { get; set; }
    public virtual ICollection<Tag> Tags { get; set; }
}

public class Company
{
    public int ID { get; set; }
    public virtual ICollection<Tag> Tags { get; set; }
}

public class Tag
{
    [Key]
    public int TagID { get; set; }
    public String Name { get; set; }

    public virtual ICollection<Project> Projects { get; set; }
    public virtual ICollection<Person> People { get; set; }
    public virtual ICollection<Company> Companies { get; set; }
}

在上下文中,映射设置如下:

modelBuilder.Entity<Tag>()
    .HasMany(t => t.Projects)
    .WithMany(p => p.Tags)
    .Map(m =>
    {
        m.MapLeftKey("ID");
        m.MapRightKey("TagID");
        m.ToTable("TagProjects");
    });


modelBuilder.Entity<Tag>()
    .HasMany(t => t.People)
    .WithMany(p => p.Tags)
    .Map(m => 
    {
        m.MapLeftKey("ID");
        m.MapRightKey("TagID");
        m.ToTable("TagPeople");
    });

modelBuilder.Entity<Tag>()
    .HasMany(t => t.Companies)
    .WithMany(p => p.Tags)
    .Map(m =>
    {
        m.MapLeftKey("ID");
        m.MapRightKey("TagID");
        m.ToTable("TagCompanies");
    });

现在,当我尝试向这样的项目添加标签时:

public void AddTagToProject(int tagId, int projectId)
{
    ProjectRepository projectRepository = new ProjectRepository();
    Project project = projectRepository.GetProjectByID(projectId);
    project.Tags.Add(GetTagByID(tagId));

    Save();
}

也不例外,但该项目也没有添加任何标签。有人知道在哪里看吗?

public Tag GetTagByID(int tagId) 
{ 
    return db.Tags
        .Where(t => t.TagID == tagId)
        .First(); 
}

我找到了解决方案,问题是项目没有正确更新并且值从未保存。

【问题讨论】:

  • GetTagByID 函数代码是什么样的?
  • 公共标签 GetTagByID(int tagId) { return db.Tags.Where(t => t.TagID == tagId).First(); }
  • 一些额外的信息。标签在插入时正确创建,但已创建 bij Code First 的可连接件未填充。任何想法为什么?当我手动播种此表时,项目会显示正确的标签。我必须自己设置可连接的值吗?

标签: c# .net asp.net-mvc-3 ef-code-first


【解决方案1】:

您是否确保您的数据库没有任何由 EF 4.1 生成的奇怪命名的列?我曾经发生过这种情况,FK 列被称为 UserTrialLicense_UserTrialLicenseID。因此,每当我尝试使用 .Include 急切加载任何内容时,它都无法正常工作。

【讨论】:

  • 我检查了数据库创建脚本,它创建了三个新的未指定表,它们看起来都像这样:create table [dbo].[TagProjects] ( [ID] [int] not null, [TagID] [int ] 不为空,主键 ([ID], [TagID]) );
  • 看起来不对,你有两个主键ID和TagID?如果 ID 应该是你的主键,那么在你的 POCO 中你应该用 [Key] 来装饰它。如果 - 在您的 POCO 中,您定义了两个(ID 和 TagID),您应该去掉一个。您使用的是 Entity Framework 4.1 Codefirst 正确吗?我刚刚注意到您的 ID 是如何设置的,您可能还想尝试为您的 PK 与所有类(ProjectID、TagID、PersonID、CompanyID)保持一致的方案。
  • 据我了解,为类提供公共 int ID 会使 Code First 将此 ID 生成为主键。对于 TagProjects 表,两个字段都是主键是正确的,因为这是多对多相关表之间的连接表。代码现在可以正常工作,问题在于标签相关的实体(项目、公司和个人)在添加标签后没有更新,因此在可连接中没有保存任何内容
  • 哦,我忘了那是一个连接表。那么它现在工作了吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-07
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多