【问题标题】:ASP.NET MVC Creating duplicate records on creating objectASP.NET MVC 在创建对象时创建重复记录
【发布时间】:2016-10-04 05:38:54
【问题描述】:

我是 ASP.NET 新手,遇到了一个非常奇怪的重复记录问题。我将在这里深入研究代码:

我有一个公司模型定义为:

public class Company
{
    [Key]
    public int ID { get; set; }

    public DateTime DateCreated { get; set; }
    public virtual SubscriptionType SubscriptionType { get; set; }

    [Required]
    [Display(Name = "Company Name")]
    public String Name { get; set; }
}

public class CompanyDBContext : DbContext
{
    public DbSet<Company> Companies { get; set; }
}

而一个 SubscriptionType 模型定义为:

public class SubscriptionType
{
    [Key]
    public int ID { get; set; }

    public string Name { get; set; }
}

public class SubscriptionTypeDBContext : DbContext
{
    public DbSet<SubscriptionType> SubscriptionTypes { get; set; }
}

SubscriptionType 数据在 Seed 函数中设置如下:

var subscriptionTypes = new List<SubscriptionType>
        {
            new SubscriptionType { Name= "Free" },
            new SubscriptionType { Name= "Business" },
            new SubscriptionType { Name= "Enterprise" },
        };
        subscriptionTypes.ForEach(s => context.SubscriptionTypes.AddOrUpdate(p => p.Name, s));
        context.SaveChanges();

当我尝试在公共异步任务注册功能中创建用户时(我使用默认的 ApplicationUser),我使用以下代码在用户注册时创建公司:

ApplicationDbContext db = new ApplicationDbContext();
            var subscription = db.SubscriptionTypes.Find(1);
            var company = new Company { Name = model.CompanyName, DateCreated = DateTime.UtcNow, SubscriptionType = subscription };
            var user = new ApplicationUser { UserName = model.Email, Email = model.Email, Company = company };
            var result = await UserManager.CreateAsync(user, model.Password);

现在 - 公司应该将 1 个设置为 SubscriptionType_ID,但相反,它会在 SubscriptionType 表中创建重复记录并将 SubscriptionType_ID 设置为 4。

ID | Name
-----------
1  | Free
2  | Business
3  | Enterprise
4  | Free

这是我的 ApplicationDBContext:

public ApplicationDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }

    public DbSet<SubscriptionType> SubscriptionTypes { get; set; }
    public DbSet<Company> Companies { get; set; }
    public DbSet<Project> Projects { get; set; }
    public DbSet<Collection> Collections { get; set; }

为什么会在这种情况下创建重复记录?

【问题讨论】:

  • 尝试将实体框架添加到您的标签列表中
  • 您的公司类需要外键的导航属性 - Relationships and Navigation Properties
  • 我尝试添加 SubscriptionTypeID - 不幸的是问题仍然存在。
  • 如果您正确定义了导航属性(并且您在保存时设置了SubscriptionTypeID 的值(而不是SubscriptionType),则问题不会持续存在
  • 但是当SubscriptionType 像在问的问题中那样分配时,它应该真的有效,不是吗?我的意思是您不必显式分配外键。

标签: c# asp.net asp.net-mvc


【解决方案1】:

您正在创建 Company 类的新实例 - 从 Entity Framework 的角度来看 - 它是全新的 Company,恰好具有相同的 Name 值(您可以在此处阅读更多信息:Entity Framework Change Tracking )。

您应该适当地检查用户提供的公司是否已存在于您的数据库中,如果存在,则应检索该公司并将其分配给ApplicationUser 类中的Company 属性。

【讨论】:

  • 感谢您的回复,但重复的记录是 SubscriptionType。应该只有 3 个,是在 Seed 函数中创建的,但由于某种原因,当我创建新公司时,它正在创建重复记录。
  • 哦,对不起 - 我错过了我们正在谈论的那部分 SubscriptionType。您是否尝试过使用var subscription = db.SubscriptionTypes.FirstOrDefault(type =&gt; type.ID == 1);? Find 按主键执行搜索 - 如果FirstOrDefault 不会导致重复的SubscriptionType,那么我猜ID 是主键有问题。
  • 我刚刚尝试了您的建议 - 但它似乎仍在 SubscriptionType 表中创建新记录。
  • 我刚刚意识到一件可疑的事情——实体框架中的更改跟踪是由 DbContext 在内部完成的,但 SubscriptionType 和 Company 位于两个不同的 DbContext 中。这两个在两个不同的数据库中吗?您正在将更改保存到另一个第三个 ApplicationDbContext,因此此上下文不知道此检索到的 SubscriptionType 是“旧”实体,并且可能将其视为新实体。您是否尝试将 Companies 和 SubscriptionTypes 放在一个 DbContext 中并使用此 DbContext 来保存您的数据?
  • 另一个想法,如果SubscriptionType 确实在ApplicationDbContext 中,则将attaching 这个实体关联到上下文。如果它们在相同的上下文中,那么您的代码应该可以工作(据我所知),但也许还有更多事情发生,这未包含在您的问题的 sn-ps 中。
猜你喜欢
  • 1970-01-01
  • 2013-03-10
  • 1970-01-01
  • 1970-01-01
  • 2014-11-26
  • 1970-01-01
  • 2020-03-13
  • 2023-02-07
  • 1970-01-01
相关资源
最近更新 更多