ASP.NET Core Linq - c#

There is a request for the following plan:
[HttpPost]
public async Task<IActionResult> Ref(RefModel model)
{
var countreward = from c in db.Person
join g in db.Referal
on c.AccountID equals g.memb___id into gg
from ggg in gg.DefaultIfEmpty()
where ggg.referal_reward >= 1
where c.RCount >= 1
orderby c.AccountID == User.Identity.Name
select new Person()
{
AccountID = c.AccountID,
Name = c.Name,
};
var reward = countreward.ToList();
if (ModelState.IsValid)
{
if (reward.Count >= 1)
{
CSData bonus = db.CSData.First(p => p.AccountID == User.Identity.Name);
bonus.GP+= 10 * reward.Count;
db.CSData.Update(bonus);
await db.SaveChangesAsync();
ViewBag.Message = "Yes";
}
else
{
ViewBag.Message = "No";
}
}
return View(model);
}
After clicking on the button, I get all the referrals I need from the Referal table, compare their login to the required criteria with the Person table and after that I get + = 10 to my login.
How do I send 5 points to those thanks to which I got 10 points? Thank you!

Right before await db.SaveChangesAsync(); add:
foreach(var person in reward)
{
CSData bonus = db.CSData.First(p => p.AccountID == person.AccountID);
bonus.GP += 5;
db.CSData.Update(bonus);
}
You should really start studying by reading a book about the basics. You don't do yourself any favors when you get stuck on simple things like iterating a list. Before doing complicated things like accessing databases and communicating over a network, make sure you can do the basics. Learn to walk before you run.

Related

loop through sql results and delete the single rows

Im trying to delete persons from a list through a for loop. My problem is now that im trying to find each id to delete the specific row of my database but i dont know how i can do it with a for loop.
My Code right now:
[HttpPost("delUebertrag/")]
public async Task<ActionResult<ProzessPersonenzuordnungen>> delRecUebertrag([FromBody] recUebertragModel user)
{
ProzessPersonenzuordnungen ppz = new();
for (var i = 0; i <= user.personList.Length; i++)
{
Guid personId = new Guid(user.personList[i]);
ppz.ProzessId = new Guid(user.prozessId);
var prozessPersonenzuordnungen = _context.ProzessPersonenzuordnungens.Where(p => p.ProzessId == ppz.ProzessId && p.PersonId == personId);
if (prozessPersonenzuordnungen == null)
{
return NotFound();
}
//Everythings works fine above, prozessPersonenzuordnungen haves for Example 2 results
for(var j = 0; j < prozessPersonenzuordnungen.Count(); j++) // i dont know if Counts is fine, looking for something like length of the results
{
var toDeletingRow = await _context.ProzessPersonenzuordnungens.FindAsync(prozessPersonenzuordnungen.Select(p => p.ProzessPersonenzuordnungId)); // Here i need to go through every singleId of my results, something like p.ProzessPersonenzuordnungId[j](does not work)
_context.ProzessPersonenzuordnungens.Remove(toDeletingRow);
await _context.SaveChangesAsync();
}
}
return Ok();
}
The FindAsync can be only used for single item. Instead do
var rowsToDelete = _context.ProzessPersonenzuordnungens.Where(x=> prozessPersonenzuordnungen.Select(p => p.ProzessPersonenzuordnungId).Contains(x.Id));
And instead of Remove, use
_context.ProzessPersonenzuordnungens.RemoveRange(rowsToDelete);
And one important thing, accessing database in a loop is a very bad practice.
Try to do it without the loop.
Edit:
Try this
ProzessPersonenzuordnungen ppz = new ProzessPersonenzuordnungen();
for (var i = 0; i <= user.personList.Length; i++)
{
Guid personId = new Guid(user.personList[i]);
ppz.ProzessId = new Guid(user.prozessId);
var prozessPersonenzuordnungen = _context.ProzessPersonenzuordnungens.Where(p => p.ProzessId == ppz.ProzessId && p.PersonId == personId)
.Select((x)=> x.ProzessPersonenzuordnungId);
if (prozessPersonenzuordnungen == null)
{
return NotFound();
}
var rowsToDelete = _context.ProzessPersonenzuordnungens.Where(x => prozessPersonenzuordnungen.Contains(x.Id));
_context.ProzessPersonenzuordnungens.RemoveRange(rowsToDelete);
await _context.SaveChangesAsync();
return Ok();
}

return response from a function while the other codes are running .netcore

I have this function :
[HttpGet]
[Route("See/{OID}")]
public IActionResult See([FromRoute]long OID)
{
//time ham bayad chek bshe
orders order = _context.orders.FirstOrDefault(e => e.OID == OID);
lastViewed lv = _context.lastViewed.FirstOrDefault(e => e.UID.ToString() == User.Identity.Name);
if (DateTime.Compare(lv.sentTime.AddSeconds(order.seconds), GetUTCDateTime()) < 0)
return Content("1");
unViewed UV = _context.unViewed.FirstOrDefault(e => e.UID.ToString() == User.Identity.Name && e.OID == OID);
if (UV != null)
_context.unViewed.Remove(UV);
coins coin = _context.coins.FirstOrDefault(e => e.UID.ToString() == User.Identity.Name);
if (order.type > 50)
coin.Coin += order.seconds * 8;
else
coin.Coin += order.seconds;
order.view--;
if (order.view == 0)
{
var uv = _context.unViewed.Where(e => e.OID == OID);
foreach (unViewed uvv in uv)
_context.unViewed.Remove(uvv);
pastOrders po = new pastOrders
{
link = order.link,
OID = order.OID,
UID = order.UID
};
_context.pastOrders.Add(po);
_context.orders.Remove(order);
}
_context.SaveChanges();
return showlink();
}
the showlink() function is an IActionResult.the showlink() is fully independent from other codes.
my question is here how to first response the showlink() to user and after that response, run the other codes ?
thanks alot.
You can schedule the rest of the code to run on a separate thread. Note, though, that this is not entirely safe as you are not checking to see if the thread properly executed. In order to do that, you would need to add other checks to your code along with a way to be notified if something fails. Adopting an asynchronous model is a big undertaking and is the long term solution.
However, the following should unblock you for this particular case:
var result = showlink();
Task.Factory.StartNew(() => {
// Rest of your code that needs to run in the background.
});
return result;

Add to int filed each time an action called?

I want to increase 1 unit of my int field named BookViews by per action run.
My Action :
[HttpGet]
public IActionResult BookDetails(int id)
{
MultiModels model = new MultiModels();
model.UserListed = (from u in _userManager.Users orderby u.Id descending select u).Take(10).ToList();
using (var db = _iServiceProvider.GetRequiredService<ApplicationDbContext>())
{
var result = from b in db.books where (b.BookId == id) select b;
if (result.Count() != 0)
{
///error occure here
db.books.Update((from b in db.books where b.BookId == id select b.BookViews) + 1));
db.SaveChanges();
}
}
return View(model);
}
But my code get error. How can i increase BookViews field 1 unit per run and update it in database?
Try retrieving the book that you want, increment your BookViews and then call SaveChanges():
var currentBook = result.ToList().FirstOrDefault();
if(currentBook != null){
currentBook.BookViews++;
db.Books.Attach(currentBook );
//Changing the State
db.Entry(currentBook ).State = EntityState.Modified;
db.SaveChanges();
}
Edit
Please try to be more especific, we are reallt trying to help you, but I cant't guess the error's that you are getting or what the varibles in your code do, if you don't explain...

LINQ to Entities Transaction Performance Issue

public void Register(decimal groupId, decimal deptId, decimal employeeId)
{
using (EmployeeEntities db = new EmployeeEntities())
{
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.Snapshot }))
{
var course = db.Courses.Where(s => s.GroupId == groupId && s.DepartmentId == deptId).ToList();
foreach (var item in course)
{
var filledSeats = db.CourseRegistrations.Count(c => c.CourseId == item.CourseId && c.DepartmentId == deptId && (c.CancelledFl == null || c.CancelledFl == false));
if (item.AllotedSeats <= filledSeats)
{
throw new Exception("Sorry! Seats are not available for " + db.Groups.Where(s => s.GroupId == item.GroupId).Select(s => s.GroupName).FirstOrDefault());
}
if (!db.CourseRegistrations.Any(s => s.EmployeeId == employeeId && s.CourseId == item.CourseId && (s.CancelledFl == false || s.CancelledFl == null)))
{
var courseRegister = new CourseRegistration();
db.CourseRegistrations.Add(courseRegister);
courseRegister.CourseId = item.CourseId;
courseRegister.EmployeeId = employeeId;
courseRegister.CreatedBy = 1;
courseRegister.CreatedDt = DateTime.Now;
courseRegister.RecordVa = 1;
item.FilledSeats = item.FilledSeats + 1;
}
}
db.SaveChanges();
scope.Complete();
}
}
}
Consider the above code. It is a function which is eventually called when a request is sent to an ASP.NET WebAPI controller.
The function simply registers an employee to a course after checking seat availability. Some 200 employees would register for courses at the same time.
I am using Snapshot Isolation for every transaction.
My problem is in performance. It is slow. Sometimes it times out.
My question is why? What part of my code have I gone wrong? What really happens in all these transactions? What waits or what locks?
You have multiple calls to the database inside your for loop, which means you eat the total cost of db request latency 2 x course.length times, when you should only need to eat it once, maybe twice. See if you can bring the necessary data from db.CourseRegistrations outside the loop, possibly as part of the same query joined with the data from Courses. Then you can do the operations inside the loop in memory, which will be orders of magnitude faster.
If you are doing many updates/inserts the EF automatically tracks these changes by default, this can really hurt performance if you are updating many records. To help this you can turn off the AutoDetectChangesEnabled feature just before you do your bulk update and then back on again as soon as you are finished;
try
{
db.Configuration.AutoDetectChangesEnabled = false;
//loop through your updates here
}
finally
{
db.Configuration.AutoDetectChangesEnabled = true;
}
db.SaveChanges();

Entity Random Select from DB C# MVC

Try to find the solution but i cant.
So problem is next one. I have the EDM model of database. I have a class with functions to get data from DB.
Like this:
public IQueryable<photos> FindUserPhotos(string userlogin)
{
return from m in db.photos
where m.userlogin == userlogin
select m;
}
How to get the Random 10 lines from DB?
I always use this method for get custom entity OrderBy(x => Guid.NewGuid())
public photos Find10RandomUserPhotos(string userlogin)
{
return db.photos.Where(x => x.userlogin == userlogin).OrderBy(x => Guid.NewGuid()).Take(10).ToList();
}
Following Random row from Linq to Sql
public photos FindRandomUserPhoto(string userlogin)
{
var qry = FindUserPhotos(userlogin);
int count = qry.Count();
int index = new Random().Next(count);
return qry.Skip(index).FirstOrDefault();
}
public Array<photos> Find10RandomUserPhotos(string userlogin)
{
var result = New Array<photos>;
for (i = 0; i < 10; i++) {
result.add(FindRandomUserPhoto(userlogin));
}
return result
}

Categories