Add to int filed each time an action called? - c#

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...

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

An exception was thrown while attempting to evaluate a LINQ query parameter expression

I got error in the tittle. Probably i must control string.IsNullOrEmpty(searchString) but i didn't it. My code bellow. Please help me
Thank you everyone i solved this problem. Problem was not here. Prooblem in my route codes. for search is different i would write my route codes this
endpoints.MapControllerRoute(
name:"search",
pattern: "{search}",
defaults: new {controller="Shop",action="search"}
);
but not in from of pattern: "{search}
should be this pattern: "search"
Thank you to everyone who helped
public List<Product> GetSearchResult(string searchString)
{
using (var context = new ShopContext())
{
var products = context
.Products
.Where(i=> i.IsApproved && (i.Name.ToLower().Contains(searchString.ToLower()) || i.Description.ToLower().Contains(searchString.ToLower())))
.AsQueryable();
return products.ToList();
}
}
I would break this up as follows:
public List<Product> GetSearchResult(string searchString)
{
// What do you want to do if searchString is null or blank? (Pick one:)
// You could send back an empty result...
if (String.IsNullOrWhiteSpace(searchString))
return null;
// Or you could convert it to a blank string
if (searchString == null)
searchString = "";
List<Product> products = new List<Product>();
using (var context = new ShopContext())
{
products = context.Products.ToList();
}
// Always check for null and empty after going to the DB
if (products == null || products.count = 0)
return null;
// If we are still here, then we can finally do the search
List<Product> results = products.Where(i=> i.IsApproved &&
(i.Name != null && i.Name.ToLower().Contains(searchString.ToLower()) ||
(i.Description != null && i.Description.ToLower().Contains(searchString.ToLower())));
return results;
}
Note: I've not tested this and there may be syntax errors in the last LINQ statement with all of the ('s and )'s.
EDIT:
The example above will pull back ALL records in the Product table and then filter the results in-memory. If you want to avoid that, then I think this should work:
public List<Product> GetSearchResult(string searchString)
{
// What do you want to do if searchString is null or blank? (Pick one:)
// You could send back an empty result...
if (String.IsNullOrWhiteSpace(searchString))
return null;
// Or you could convert it to a blank string
if (searchString == null)
searchString = "";
using (var context = new ShopContext())
{
List<Product> products = context.Products.Where(i=> i.IsApproved &&
(i.Name != null && i.Name.ToLower().Contains(searchString.ToLower()) ||
(i.Description != null && i.Description.ToLower().Contains(searchString.ToLower()))).ToList();
return products;
}
}
The key difference between this and your OP is that we are checking for null's on Name and Description -- and I believe this does it in a way that EF can translate into a query.
Not a lot of information at hand but i assume the LINQ fails because a string is null.
Also why do you create a queryable of your results and then produce a list?
public List<Product> GetSearchResult(string searchString) {
static bool Contains(string a, string b) {
return a.ToLower().Contains(b.ToLower());
}
using (var context = new ShopContext()) {
return context
.Products
.Where(i => i.IsApproved)
.Where(i => i.Name is null ? false : Contains(i.Name, searchString)
|| i.Description is null ? false : Contains(i.Description, searchString))
.ToList();
}
}

ASP.NET Core Linq

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.

Field in Database Not updating while using SubmitChanges()

I'm trying to update 2 field in my database using Database Context
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ChangeDefaultUserLockingSetting(int PasswordAttempts, int DefaultLockingTime)
{
var defaultAccountSettings = new DefaultAccountSettingsDataContext();
var defaultLockoutTimeSpam = defaultAccountSettings.DefaultAccountSettings.Where(u=>u.id==1).Select(u=>u.DefaultAccountLockoutTimeSpan).First();
var maxFailedAccessAttemptsBeforeLockout = defaultAccountSettings.DefaultAccountSettings.Where(u => u.id == 1).Select(u=>u.MaxFailedAccessAttemptsBeforeLockout).First();
//foreach (int item in defaultLockoutTimeSpam)
{
defaultLockoutTimeSpam = DefaultLockingTime;
}
maxFailedAccessAttemptsBeforeLockout = DefaultLockingTime;
defaultAccountSettings.SubmitChanges();
return View("Index", loadAdministrationViewModel());
}
What I am doing wrong?
You need to try this code.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ChangeDefaultUserLockingSetting(int PasswordAttempts, int DefaultLockingTime)
{
var defaultAccountSettings = new DefaultAccountSettingsDataContext();
var defaultLockoutTimeSpam = defaultAccountSettings.DefaultAccountSettings.Where(u => u.id == 1).FirstOrDefault();
var maxFailedAccessAttemptsBeforeLockout = defaultAccountSettings.DefaultAccountSettings.Where(u => u.id == 1).FirstOrDefault();
//foreach (int item in defaultLockoutTimeSpam)
{
defaultLockoutTimeSpam.DefaultAccountLockoutTimeSpan = DefaultLockingTime;
}
maxFailedAccessAttemptsBeforeLockout.MaxFailedAccessAttemptsBeforeLockout = DefaultLockingTime;
defaultAccountSettings.SubmitChanges();
return View("Index", loadAdministrationViewModel());
}
I was modifying the values but not the Object
This is the proper way to do it :
public ActionResult ChangeDefaultUserLockingSetting(int PasswordAttempts, int DefaultLockingTime)
{
var defaultAccountSettings = new DefaultAccountSettingsDataContext();
var accountSettings = defaultAccountSettings.DefaultAccountSettings.First(u => u.id == 1);
//The object should be modified and not his local value
accountSettings.DefaultAccountLockoutTimeSpan = DefaultLockingTime;
accountSettings.MaxFailedAccessAttemptsBeforeLockout = PasswordAttempts;
defaultAccountSettings.SubmitChanges();
return View("Index", loadAdministrationViewModel());
}

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