#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
существует, было бы привязать эту сущность к контексту. Если они находятся в одном контексте, то ваш код должен работать (насколько я могу судить), но, возможно, происходит что-то еще, что не включено в фрагменты вашего вопроса.