ASP.NET MVC, создающий повторяющиеся записи при создании объекта

#c# #asp.net #asp.net-mvc

#c# #asp.net #asp.net-mvc

Вопрос:

Я новичок в 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 устанавливаются в начальной функции следующим образом:

 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; }
  

Зачем в этом случае создавать дублирующуюся запись?

Комментарии:

1. попробуйте добавить entity framework в свой список тегов

2. Вашему классу company требуется свойство навигации для внешних связей ключей и свойств навигации

3. Я попытался добавить SubscriptionTypeID — к сожалению, проблема сохраняется.

4. Проблема не будет сохраняться, если вы правильно определили свои свойства навигации (и вы установили значение SubscriptionTypeID при сохранении (нет SubscriptionType )

5. Но это действительно должно работать, когда SubscriptionType назначается, как в заданном вопросе, не так ли? Я имею в виду, что вам не нужно явно назначать внешний ключ.

Ответ №1:

Вы создаете новый экземпляр своего Company класса — с точки зрения Entity Framework — он совершенно новый Company , который имеет то же Name значение (подробнее вы можете прочитать здесь: Отслеживание изменений Entity Framework).

Вы должны надлежащим образом проверить, существует ли компания, предоставленная пользователем, в вашей базе данных, и если это так, вы должны получить эту компанию и назначить ее Company свойству в ApplicationUser классе.

Комментарии:

1. Спасибо за ответ, но дублирующаяся запись — это SubscriptionType . Должно быть только 3, которые создаются в начальной функции, но по какой-то причине она создает дублирующуюся запись, когда я создаю новую компанию.

2. О, извините — я пропустил ту часть, о которой мы говорим SubscriptionType . Вы пробовали использовать var subscription = db.SubscriptionTypes.FirstOrDefault(type => type.ID == 1); ? Поиск выполняет поиск по первичному ключу — если FirstOrDefault не приведет к дублированию SubscriptionType , то, я думаю, что-то не так с идентификатором, являющимся первичным ключом.

3. Я только что попробовал ваше предложение сейчас, но, похоже, оно все еще создает новую запись в таблице SubscriptionType.

4. Я только что понял одну подозрительную вещь — отслеживание изменений в Entity Framework внутренне выполняется DbContext, но SubscriptionType и Company находятся в двух разных DbContexts. Эти две находятся в двух разных базах данных? Вы сохраняете изменения в еще одном третьем ApplicationDbContext, поэтому этот контекст не имеет понятия о том, что этот извлеченный SubscriptionType является «старым» объектом и, возможно, рассматривает его как новый. Вы пытались поместить Companies и SubscriptionTypes в один DbContext и использовать этот DbContext для сохранения ваших данных?

5. Другой идеей, если SubscriptionType она действительно ApplicationDbContext существует, было бы привязать эту сущность к контексту. Если они находятся в одном контексте, то ваш код должен работать (насколько я могу судить), но, возможно, происходит что-то еще, что не включено в фрагменты вашего вопроса.