Violation of PRIMARY KEY constraint 'PK_Currencies'. Cannot insert duplicate key in object - sql-server

I am working on blazor server. I have the following class structure for my project.
I have for this error three classes.
ApplicationUser class:
public class ApplicationUser
{
public Guid ApplicationUserID { get; set; }
[Required (ErrorMessage = "Name is required")]
public string Name { get; set; } = null!;
[Required(ErrorMessage = "Surname is required")]
public string Surname { get; set; } = null!;
[Required(ErrorMessage = "Email is required")]
public string Email { get; set; } = null!;
[Required(ErrorMessage = "Password is required")]
public string Password { get; set; } = null!;
[Required(ErrorMessage = "Salary pay date is required")]
public DateTime? SalaryPaymentDate { get; set; }
[Required(ErrorMessage = "Salary amount is required")]
public Decimal? SalaryAmount { get; set; }
[Required (ErrorMessage = "Currency is required")]
public Guid? CurrencyID { get; set; }
public Currency? Currency { get; set; }
public List<CreditCard>? CreditCards { get; set;}
public List<Saving>? Savings { get; set;}
public List<Expense>? Expenses { get; set;}
}
Currency class:
public class Currency
{
public Guid CurrencyID { get; set; }
public string CurrencyName { get; set; } = null!;
public string CurrencyAbbreviation { get; set; } = null!;
public string? CurrencySymbol { get; set; }
public List<ApplicationUser>? ApplicationUsers { get; set; }
}
I seeded the currency class with three values namely:
- USD
- ZAR
- Euro
`Savings` class:
public class Saving
{
public Guid SavingID { get; set; }
public List<Goal>? Goals { get; set; }
public Guid? ApplicationUserID { get; set; }
public ApplicationUser? ApplicationUser { get; set; }
}
So what I am trying to do is when you open the savings view for the first time and the Get method returns 0 values I create a new SavingObject.
In this SavingObject, I assign the CurrentUser which is passed as a cascading parameter and it does have a value.
Then I run my AddMethod to create the saving object. Here is the method:
[CascadingParameter]
public ApplicationUser? CurrentUser { get; set; }
protected override async Task OnInitializedAsync()
{
Savings = await savingsservice.Get();
if (Savings?.Count > 0)
SavingObject = Savings.FirstOrDefault();
else
{
SavingObject = new Saving();
SavingObject.ApplicationUser = CurrentUser!;
SavingObject.ApplicationUserID = CurrentUser!.ApplicationUserID;
await savingsservice.Add(SavingObject);
DataChanged();
}
Goals = await goalsservice.Get();
}
But it then crashes with the following message once the add method is run:
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while saving the entity changes. See the inner exception for details.
Microsoft.Data.SqlClient.SqlException (0x80131904): Violation of PRIMARY KEY constraint 'PK_Currencies'. Cannot insert duplicate key in object 'dbo.Currencies'. The duplicate key value is (c80b1fe5-7d94-4fc5-8328-706db7f29a18).
Violation of PRIMARY KEY constraint 'PK_ApplicationUsers'. Cannot insert duplicate key in object 'dbo.ApplicationUsers'. The duplicate key value is (1d03c731-3034-498b-fef5-08db0eaad3f6).
I understand that it states cannot insert duplicate key for the user and currency but why does it want to insert a duplicate key I don't understand because I am assigning the user so it already has the ID and the CurrencyID?
Also my Savings table is empty and I only have one applicationUser in my table which has one Currency.
Can someone please assist as I can't find any answer online.
I have googled the problem but I can't find my specific problem online therefore I am creating a question.
I have also setup the dbcontext as I thought this might have been the problem.
modelBuilder.Entity<ApplicationUser>()
.HasMany(a => a.Savings)
.WithOne(a => a.ApplicationUser)
.HasForeignKey(a => a.ApplicationUserID)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<ApplicationUser>()
.HasMany(a => a.CreditCards)
.WithOne(a => a.ApplicationUser)
.HasForeignKey(a => a.ApplicationUserID)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<ApplicationUser>()
.HasMany(a => a.Expenses)
.WithOne(a => a.ApplicationUser)
.HasForeignKey(a => a.ApplicationUserID)
.OnDelete(DeleteBehavior.Cascade);
Here is my Savings.cs service:
namespace MoneyTracker.Services
{
public interface ISavingsService
{
Task<List<Saving>> Get();
Task<Saving> Get(Guid id);
Task<Saving> Add(Saving Saving);
Task<Saving> Update(Saving Saving);
Task<Saving> Delete(Guid id);
void DetachEntity(Saving Saving);
}
public class SavingsService : ISavingsService
{
private readonly ApplicationDbContext _context;
public SavingsService(ApplicationDbContext context)
{
_context = context;
}
public async Task<List<Saving>> Get()
{
return await _context.Savings
.Include(a => a.Goals)
.AsSplitQuery()
.ToListAsync();
}
public async Task<Saving> Get(Guid id)
{
var Saving = await _context.Savings.FindAsync(id);
return Saving;
}
public async Task<Saving> Add(Saving Saving)
{
_context.Savings.Add(Saving);
await _context.SaveChangesAsync();
return Saving;
}
public async Task<Saving> Update(Saving Saving)
{
_context.Entry(Saving).State = EntityState.Modified;
await _context.SaveChangesAsync();
return Saving;
}
public async Task<Saving> Delete(Guid id)
{
var Saving = await _context.Savings.FindAsync(id);
_context.Savings.Remove(Saving);
await _context.SaveChangesAsync();
return Saving;
}
public void DetachEntity(Saving Saving)
{
_context.Entry(Saving).State = EntityState.Detached;
}
}
}

Related

INSERT statement conflicted with foreign key constraint - SQL Server/Entity Framework Core

I get this error in my .NET Core 3.1 app:
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_DiaryDiaryEntry". The conflict occurred in database "xxxxxx", table "dbo.Diaries", column 'Id'.
I can't see anything wrong with the tables themselves.
public partial class Diaries
{
public long Id { get; set; }
public string CoverImage { get; set; }
public short Year { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public long ChildId { get; set; }
public Children Child { get; set; }
public ICollection<DiaryEntries> DiaryEntries { get; set; }
}
public partial class DiaryEntries
{
public long Id { get; set; }
public DateTime Date { get; set; }
public string Content { get; set; }
public long DiaryId { get; set; }
public Diaries Diary { get; set; }
public ICollection<Images> Images { get; set; }
}
My code? Probably an entirely different matter.
This is the code that generates the error.
[HttpPost("CreateYear/{id}")]
public async Task<IActionResult> CreateYearOfEntries([FromRoute] int id)
{
// The id is the ID of an existing diary
// Make sure the diary does exist first and that it belongs to the current logged-in user
var diary = _diaryRepository.Find(id);
if (diary == null) return NotFound();
var year = diary.Result.Year;
if (await _diaryEntryRepository.OwnerIsLoggedIn(LoggedInUser.ParentId, id))
{
var noOfDays = DateTime.IsLeapYear(year) ? 366 : 365;
var i = 0;
for (; i < noOfDays; i++)
{
var date = new DateTime(year, 1, 1).AddDays(i);
var newDiaryEntry = new DiaryEntries()
{
Content = " ",
Date = date,
DiaryId = diary.Id
};
await _diaryEntryRepository.Add(newDiaryEntry);
}
return Ok();
}
return NotFound();
}
public class DiaryEntryRepository : IDiaryEntryRepository
{
private readonly ApplicationDbContext _context;
public DiaryEntryRepository(ApplicationDbContext context)
{
_context = context;
}
public async Task<DiaryEntries> Add(DiaryEntries diaryEntry)
{
await _context.DiaryEntries.AddAsync(diaryEntry);
await _context.SaveChangesAsync();
return diaryEntry;
}
}

Invalid column name exception thrown in .NET Core web api

I have two classes in my database which are defined as classes, fed into entity and then called from the API
The full method is below for the calls. The first call works fine, the second throws the exception
public async Task<ActionResult<List<QuizForms>>> GetQuiz([FromQuery]string id)
{
var form = await _context.QuizForms.Where(t=>t.QuizId == id).ToListAsync();
if (form == null)
{
return NotFound();
}
var elem = new List<Element>();
foreach(var e in form)
{
var data = await _context.Element.Where(t => t.ElementId == e.ElementId).ToListAsync();
elem.AddRange(data);
e.Element.AddRange(elem);
}
return form;
}
When the var data line is hit, an excception is thrown
Microsoft.Data.SqlClient.SqlException (0x80131904): Invalid column name 'QuizFormsFormId'.
It looks like the name of the class and column name are being concatenated and the used as the query parameter.
The two classes look like this
public class QuizForms
{
[Key]
public int FormId { get; set; }
public string QuizId { get; set; } = "";
#nullable enable
public string? Title { get; set; }
public int? ElementId { get; set; }
public List<Element>? Element { get; set; }
public int? PreviousId { get; set; }
public int? NextId { get; set; }
#nullable disable
}
and
public class Element
{
[Key]
public int Id { get; set; }
public int ElementId { get; set; }
#nullable enable
public int? MathsId { get; set; }
public int? QuestionId { get; set; }
public int? InformationId { get; set; }
public int? AnswerId { get; set; }
#nullable disable
public string QuizId { get; set; } = "";
}
Is it because I'm not using Id for the primary key or do I need to do something else so the class and property aren't concatented like this?

EF Core Add-Migration generating extra column with ColumnName1

I have the following entities when I generate migration it creates two columns with name RestrictedCategoryId and RestrictedCategoryId1(FK). How to solve this issue to generate only one column with FK?
Note: I need OrderId in each entity.
`C#
public class Order
{
public Guid Id { get; set; }
public DateTime OrderDate { get; set; }
private List<Category> _categories;
public List<Category> Categories => _categories;
}
public class Category
{
public Guid Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public Guid OrderId { get; set; }
public Order Order { get; set; }
private List<RestrictionCategory> _restrictedCategories;
public List<RestrictionCategory> RestrictedCategories => _restrictedCategories;
}
public class RestrictionCategory
{
public Guid Id { get; set; }
public string Name { get; set; }
public Guid OrderId { get; set; }
public Order Order { get; set; }
public Guid CategoryId { get; set; }
public Category Category { get; set; }
public Guid RestrictedCategoryId { get; set; }
public Category RestrictedCategory { get; set; }
}
public class OrderConfiguration : IEntityTypeConfiguration<Order>
{
public void Configure(EntityTypeBuilder<Order> builder)
{
builder.HasKey(o => o.Id);
builder.Property(o => o.Id).IsRequired();
}
}
public class CategoryConfiguration : IEntityTypeConfiguration<Category>
{
public void Configure(EntityTypeBuilder<Category> builder)
{
builder.HasKey(c => new { c.Id, c.OrderId });
builder.Property(o => o.Id).IsRequired();
builder.Property(o => o.OrderId).IsRequired();
builder.HasMany(c => c.RestrictedCategories).WithOne(cr => cr.Category)
.HasForeignKey(cr => new { cr.CategoryId, cr.OrderId
}).OnDelete(DeleteBehavior.NoAction);
}
}
public class RestrictionCategoryConfiguration : IEntityTypeConfiguration<RestrictionCategory>
{
public void Configure(EntityTypeBuilder<RestrictionCategory> builder)
{
builder.HasKey(c => new { c.Id, c.OrderId });
builder.Property(o => o.Id).IsRequired();
builder.Property(o => o.OrderId).IsRequired();
builder.HasIndex(cr => new { cr.RestrictedCategoryId, cr.OrderId });
}
}
`
The entities resembles to actual ones.
Actually you get two additional columns:
RestrictedCategoryId = table.Column<Guid>(nullable: false),
RestrictedCategoryId1 = table.Column<Guid>(nullable: true), // <--
RestrictedCategoryOrderId = table.Column<Guid>(nullable: true) // <--
Apparently EF Core Foreign Key Conventions doesn't play well with composite keys, so you have to explicitly configure the relationship - similar to what you did for the other relationship, just since your model has no corresponding collection navigation property you have to use HasMany with generic type argument and no parameters, e.g. inside CategoryConfiguration:
builder.HasMany<RestrictionCategory>()
.WithOne(cr => cr.RestrictedCategory)
.HasForeignKey(cr => new { cr.RestrictedCategoryId, cr.OrderId})
.OnDelete(DeleteBehavior.NoAction);

Sending object to sql server in ASP.NET MVC4 Architecture

I am getting an exception on db.CrimeReports.Add(i);
"An exception of type 'System.Data.Entity.Infrastructure.DbUpdateException' occurred in EntityFramework.dll but was not handled in user code "
[HttpPost]
public void Test(HttpPostedFileBase file)
{
if (ModelState.IsValid)
{
using (UsersContext db = new UsersContext())
{
//db.LoginData.Add(new LoginData { UserId = 4, Username = "maria", Password ="rahat"});
byte[] image = new byte[file.ContentLength];
file.InputStream.Read(image, 0, image.Length);
var i = new CrimeReport { ImageName = "murder", ImageContent = image, Active =false};
db.CrimeReports.Add(i);
db.SaveChanges();
}
}
else
{
ModelState.AddModelError("UserName", "User name already exists. Please enter a different user name.");
}
}
Here is my CrimeReport class
[Table("CrimeReport")]
public class CrimeReport
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public int ImageId { get; set; }
public string ImageName { get; set; }
public byte[] ImageContent { get; set; }
public string Createdby { get; set; }
public System.DateTime CreatedDt { get; set; }
string Updatedby { get; set; }
public Nullable<System.DateTime> UpdatedDt { get; set; }
public bool Active { get; set; }
public virtual ReportDescription ReportDescription { get; set; }
}

The Insert statement conflict with the FOREIGN KEY constraint. Entity Framework

my models are as follows...
public class Company
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
[Required]
[MaxLength(50)]
public string Name { get; set; }
[Required]
[MaxLength(255)]
public string Fullname { get; set; }
public bool HasFuneralInsuranceParlours { get; set; }
public bool HasFuneralInsurancePolicies { get; set; }
public bool HasLifeInsurancePolicies { get; set; }
public bool IsDeleted { get; set; }
public virtual List<Office> Offices { get; set; }
}
public class Office
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
[MaxLength(50)]
public string Name { get; set; }
[MaxLength(100)]
public string Address1 { get; set; }
[MaxLength(100)]
public string Address2 { get; set; }
[MaxLength(100)]
public string Address3 { get; set; }
[MaxLength(20)]
public string Telephone { get; set; }
[MaxLength(20)]
public string Fax { get; set; }
[MaxLength(255)]
public string Email { get; set; }
public bool IsDeleted { get; set; }
public Guid CompanyId { get; set; }
public virtual Company Companies { get; set; }
public virtual List<Employee> Employees { get; set; }
}
and controllers
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(OfficeModel model)
{
bool success = false;
string message = "";
byte[] logo = null;
var user = SecurityHelper.GetAuthenticatedUser(this.HttpContext);
try
{
if (ModelState.IsValid)
{
if (model.Name.IsNullOrWhitespace()) throw new Exception("Unable to create this Employee Name. The Type cannot be blank or spaces.");
if (models.Offices.Any(x => x.Name.ToLower() == model.Name.ToLower())) throw new Exception(string.Format("This Office's Name '{0}' already exists. Please check your data.", model.Name.ToUpperCase()));
var entry = new Office
{
Id = Guid.NewGuid(),
Name = model.Name.ToUpperCase(),
Address1 = model.Address1.ToUpperCase(),
Address2 = model.Address2.ToUpperCase(),
Address3 = model.Address3.ToUpperCase(),
Telephone = model.Telephone.ToUpperCase(),
Fax = model.Fax.ToUpperCase(),
Email = model.Email.ToUpperCase(),
IsDeleted = false,
CompanyId = user.CompanyId,
Bankings = new List<Banking>()
{
new Banking
{
Bank = model.OfficeBank.ToUpperCase(),
Account = model.BankAccount.ToUpperCase(),
Branch = model.Branch.ToUpperCase(),
BranchNo = model.BranchNo.ToUpperCase(),
AccountType = model.AccountType.ToUpperCase()
}
}
};
models.Offices.Add(entity);
success = true;
return RedirectToAction("Index");
}
else
{
message = "An error was cought please check your data and retry";
}
}
catch (Exception ex)
{
message = ex.Message;
}
return View(model);
}
when l debug the above code l return the following error
"The INSERT statement conflicted with the FOREIGN KEY constraint
\"FK_dbo.Offices_dbo.Companies_CompanyId\". The conflict occurred in
database \"PolicyManager\", table \"dbo.Companies\", column
'Id'.\r\nThe statement has been terminated."
When l hover model.Name l am return a value but the rest return me a null value which l suspect the thus the cause of the the above error.
What problem can it possible be because l have used the similar code before and it worked. May anyone help. Thank you in advance
You are adding a New Office.
The error says that there is a referential integrity problem With the Foreign key constraint to the Company table.
When you create the Order you add the following Company key:
CompanyId = user.CompanyId
So it appears that user.CompanyId is not an id that is registered against an existing Company.

Resources