Reputation: 439
I have a scenario, I have users submitting entries to an API endpoint and a flag is updated as 1 on the database. A user can submit more than entry as per there feel and need per time. I have a logic that checks if an entry already exists, and if a user submits another form, the previous form is set to 0 and the new form is set to 1. Whenever I submit a second entry I end up with an error
The entity type 'EntityQueryable' was not found. Ensure that the entity type has been added to the model. at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.GetOrCreateEntry(Object entity)
this is my logic for checking
public async Task<Entrys> AddEntrys(Entrys entrys)
{
var pastSurveys = _context.Entrys.Where(e => e.UpdatedBy == entrys.UpdatedBy && e.Month == entrys.Month
&& e.Day == entrys.Day && e.Year == entrys.Year && e.CurrentStatus==true).AsQueryable();
if (pastSurveys.Count() > 0)
{
foreach (Entrys e in pastSurveys)
{
if (e.CurrentStatus == true)
{
e.CurrentStatus = false;
}
}
_context.Add(pastSurveys);
_context.SaveChanges();
}
entrys.Id = Guid.NewGuid().ToString();
_context.Add(entrys);
_context.SaveChanges();
return entrys;
}
How can I have my logic to keep on checking the existing surveys and updating them to 0 while new ones are set to 1 without getting the error above, Have tried researching no luck do far. Thank you in advance
Upvotes: 1
Views: 2792
Reputation: 31
I have faced the same problem and researched a lot to solve it. I have gone through the list of solution given above, from that instead of adding one by one object into the database takes more database Operations and more amount of time, instead using AddRange()
method parameter will accepts a list of object and save them in a single database Operation which save our time.
The optimized method
public async Task<Entrys> AddEntrys(Entrys entrys)
{
try
{
if (entrys != null)
{
var pastSurveys = _context.Entrys
.Where(e => e.UpdatedBy == entrys.UpdatedBy && e.Month == entrys.Month
&& e.Day == entrys.Day && e.Year == entrys.Year && e.CurrentStatus == true)
.ToList();
if (pastSurveys != null && pastSurveys.Any()) //Any() Checks whether pastSurveys has at once one object is present or not
{
List<Entrys> entries = new();
foreach (Entrys e in pastSurveys)
{
Entrys entry = new {
//Add all the class members as you want
//For example,
CurrentStatus = false,
Id = Guid.NewGuid().ToString()
};
entries.Add(entry);
}
_context.AddRange(entrys);
_context.SaveChanges();
return entrys;
}
else
{
return null;
}
}
else
{
return null;
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
}
Upvotes: 1
Reputation: 27376
Problem that instead of Updating entities you inserts them. Also you do not need two SaveChanges
calls. pastSurveys.Count()
also executes unwanted query.
Corrected method:
public async Task<Entrys> AddEntrys(Entrys entrys)
{
var pastSurveys = _context.Entrys
.Where(e => e.UpdatedBy == entrys.UpdatedBy && e.Month == entrys.Month
&& e.Day == entrys.Day && e.Year == entrys.Year && e.CurrentStatus == true)
.ToList();
foreach (Entrys e in pastSurveys)
{
e.CurrentStatus = false;
}
entrys.Id = Guid.NewGuid().ToString();
_context.Add(entrys);
_context.SaveChanges();
return entrys;
}
Upvotes: 4
Reputation: 858
Hi @arrif from your implementation
change the _context.Add(pastSurveys);
to _context.UpdateRange(pastSurveys);
From your current setup you adding instead of updating the flag. Try that and tell if it works cheers
Upvotes: 1