I'm using EF4.0 and I'm trying to delete a record from the database, but my code keeps throwing the following exception:
A first chance exception of type 'System.Data.UpdateException'
occurred in System.Data.Entity.dll
Here's my code:
public bool ApproveUser(string username)
{
using (var context = new UserRegistrationEntities())
{
// The entry object gets populated correctly
var entry = context.PendingApprovals
.Where(e => e.Username.Equals(username))
.FirstOrDefault();
try
{
context.DeleteObject(entry);
// Also tried context.PendingApprovals.DeleteObject(entry)
context.SaveChanges();
return true;
}
catch
{
return false;
}
}
}
I've stepped through the code and the exception is being thrown at context.SaveChanges();
Am I missing anything? Any help would be much appreciated!
Thanks in advance
Have you set the breakpoint and see if entry has value or not? Try this?
public bool ApproveUser(string username)
{
using (var context = new UserRegistrationEntities())
{
// The entry object gets populated correctly
var entry = context.PendingApprovals
.First(e => e.Username.Equals(username))
if (entry != null) {
try
{
context.PendingApprovals.DeleteObject(entry);
context.SaveChanges();
return true;
}
catch
{
return false;
}
}
}
return false;
}
Try removing it first:
public bool ApproveUser(string username)
{
using (var context = new UserRegistrationEntities())
{
// The entry object gets populated correctly
var entry = context.PendingApprovals
.Where(e => e.Username.Equals(username))
.FirstOrDefault();
try
{
context.PendingApprovals.Remove(entry);
context.DeleteObject(entry);
// Also tried context.PendingApprovals.DeleteObject(entry)
context.SaveChanges();
return true;
}
catch
{
return false;
}
}
}
Related
I have a problem saving the changes to Database Context. When i don't save i can see that the listing status is successfully changed , but when i try to save it I get an error which is saying : " There is already an open DataReader associated with this Connection which must be closed first." And i don't know where that comes from. When i try to do it asynchronous i get the same error.
AdministratorController.cs
[Route("/Admin")]
[ApiController]
public class AdministratorController : Controller
{
private readonly dbContext _dbContext;
public AdministratorController(dbContext dbContext)
{
_dbContext = dbContext;
}
///////////////////////////////////
/// //
/// Accept or Reject Listings //
/// //
//////////////////////////////////
[HttpPost]
[Route("acceptListing/{listingId}")]
[AllowAnonymous]
//[Authorize(Roles="Administrator")]
public ActionResult AcceptList([FromRoute]int listingId)
{
if (!ModelState.IsValid)
{
return BadRequest();
}
if (listingId == null)
{
return NotFound("Listing not found.");
}
foreach (Listing listing in _dbContext.Listings)
{
Console.WriteLine(listing.Status);
if(listing.Id == listingId)
{
if(listing.Status == ListingStatus.Accepted)
{
return BadRequest("Listing already accepted.");
}
else
{
listing.Status = ListingStatus.Accepted;
Console.WriteLine(listing.Status);
_dbContext.SaveChanges();
}
return Ok();
}
}
return BadRequest("Couldn't find right listing.");
}
Rather than looping through all listings looking for the one with the Id you want, just filter and get.
Listing? listing = _dbContext.Listings.FirstOrDefault(l => l.Id == listingId);
if (listing is null)
{
return BadRequest("Couldn't find right listing.");
}
if(listing.Status == ListingStatus.Accepted)
{
return BadRequest("Listing already accepted.");
}
listing.Status = ListingStatus.Accepted;
Console.WriteLine(listing.Status);
_dbContext.SaveChanges();
return Ok();
The problem here is that you are iterating the data being fetched from database and in the same time you are trying to save something from the same context. Quick fix is to use ToList in foreach:
foreach (Listing listing in _dbContext.Listings.ToList())
{
// ..
}
But in general you should not fetch everything from the database to process only one item. Just write query that will filter everything on database side. Something along this lines (not tested):
var listing = _dbContext.Listings.FirstOrDefault(l => l.Id == listingId);
if (listing is null)
{
return NotFound();
}
if (listing.Status == ListingStatus.Accepted)
{
return BadRequest("Listing already accepted.");
}
else
{
listing.Status = ListingStatus.Accepted;
Console.WriteLine(listing.Status);
_dbContext.SaveChanges();
}
return Ok();
change the code like this :
var listings = _dbContext.Listings.Tolist();
foreach (Listing listing in listings)
{
Console.WriteLine(listing.Status);
if(listing.Id == listingId)
{
if(listing.Status == ListingStatus.Accepted)
{
return BadRequest("Listing already accepted.");
}
else
{
listing.Status = ListingStatus.Accepted;
Console.WriteLine(listing.Status);
_dbContext.Update(listing);
_dbContext.SaveChanges();
}
return Ok();
}
}
I would like to update data using C# and Entity Framework Core.
But the result of Swagger is different from the result of executing the API in axios.
The variable "todoList" is stored with data in Swagger and returned null in axios.
Why a value of "todoList" is null?
Please tell me about it.
Thank you!
This is a Code.
public bool updateCompFlg(string operatorId, string id)
{
// Call Update!
// "_repository is an Interface."
if (_repository.Update(operatorId, id))
{
return true;
}
else
{
return false;
}
}
This is the code that actually updates the data.
public bool Update(string operatorId, string id)
{
// ★The results here are different.
var todoList = _context.TODOLIST.Where(u => u.seqNo.Equals(id)).FirstOfDefault();
todoList.operatorId = operatorId;
todoList.resultFlg = "1";
_context.Update(todoList);
try
{
_context.SaveChange();
return true;
}
catch (SystemException ex)
{
throw ex;
}
}
Hi I am tryin to use Transactions in my application which coded in MVC.net
I have my dbcontext in a layer and I reach it from a business layer. When I run the code its not giving me any errors but its also not making the transaction at all.
This is my context
public class DB : IDisposable
{
public DB()
{
}
private RootDYSContext _ctx = null;
public RootDYSContext ctx
{
get
{
if (_ctx == null)
_ctx = new RootDYSContext();
return _ctx;
}
set
{
_ctx = value;
}
}
public bool Commit()
{
try
{
ctx.SaveChanges();
}
catch (Exception exp)
{
Mesaj = exp.Message;
return false;
}
return true;
}
}
And this is how I am tryin to do transaction which based on here "https://learn.microsoft.com/en-us/ef/core/saving/transactions"
public bool CreateKullanici(VMKullanici
KullaniciData,List<VMRol>RolDataList,VMRol AnaRolData)
{
string mesaj = "";
int kullanici_id;
using (RootDBHelper.DB db = new RootDBHelper.DB())
{
using (var ctx = new RootDBLayer.RootDYSContext())
{
using (DbContextTransaction dbContextTransaction =
ctx.Database.BeginTransaction())
{
try
{
kullanici_id = SaveKullanici(KullaniciData, out
mesaj);
foreach(VMRol rol in RolDataList)
{
VMKullaniciRol KullaniciRolInsertData = new
VMKullaniciRol();
KullaniciRolInsertData.kullanici_id =
kullanici_id;
KullaniciRolInsertData.rol_id = rol.rol_id;
if (rol.rol_id == AnaRolData.rol_id)
KullaniciRolInsertData.ana_rol_mu =
(int)RConstants.EvetHayir.Evet;
else
KullaniciRolInsertData.ana_rol_mu =
(int)RConstants.EvetHayir.Hayir;
bKullaniciRol.SaveKullaniciRol(KullaniciRolInsertData, out mesaj);
}
/*Edit:I think this line made confusion I put this to make sure rollback
dbContextTransaction.Rollback(); */
dbContextTransaction.Commit();
return true;
}
catch
{
dbContextTransaction.Rollback();
return false;
}
}
}
}
}
I expect when I run this I shouldnt get any record at all.I seriously stucked because I dont get any error or any hint at all and this method keeps saving data regardless of rollback.
Thank you in advance.
Edit: I do my save changes part on the insert methods
Adding also code examples for the methods
public int SaveKullanici(VMKullanici KullaniciData, out string mesaj)
{
using (RootDBHelper.DB db = new RootDBHelper.DB())
{
mesaj = "";
PKullanici pKullanici = new PKullanici();
if (KullaniciData.kullanici_id == default(int))
pKullanici.InsertKullanici(db.ctx, KullaniciData);
else
pKullanici.UpdateKullanici(db.ctx, KullaniciData);
if (db.Commit())
{
return KullaniciData.kullanici_id;
}
else
{
mesaj = db.Mesaj;
return -1;
}
}
}
public void InsertKullanici(RootDYSContext ctx, VMKullanici KullaniciData)
{
ctx.TKullanici.Add(KullaniciData.TKullanici);
}
I think your problem is that you do commit and then you want to rollback but you should one thing commit or rollback.
In addition I cant see in your code where you actually doing transaction.commit. Your code has commit function but commit != savechanges.
Idea of transactions (there are different type but) is that you save data to database do some validation or operations and then you say well it looks ok commit or there is an error do rollback.
Also note if you are not do not commit or do rollback then your identity field will get incremented no matter what
I have the following class:
[ClaimsPrincipalPermission(SecurityAction.Demand, Operation = "view", Resource = "agreement")]
public class AgreementViewModel : Screen
{
[ClaimsPrincipalPermission(SecurityAction.Assert, Operation = "save", Resource = "agreement")]
public async void Save()
{
}
}
My problem is that even though the principal has both claims specified above, the call to Save fails. If i take off the claims from class level it works fine. The class also instantiates just fine. My "manual" check to figure out if the user can execute action works fine, it's the actual execution the fails. Manual check is defined as following:
public bool CanExecute(object sender, [CallerMemberName] string callerMethod = null)
{
string targetMethodName = callerMethod;
if (callerMethod == null)
return true;
if (callerMethod.StartsWith("Can"))
targetMethodName = callerMethod.Substring(3, callerMethod.Length - 3);
if (string.IsNullOrEmpty(targetMethodName))
return true;
var claimsAttribute = sender.GetType().GetMethods()
.Where(x => x.Name == targetMethodName)
.SelectMany(x => x.GetCustomAttributes(typeof(ClaimsPrincipalPermissionAttribute), true).Cast<ClaimsPrincipalPermissionAttribute>())
.FirstOrDefault();
return CanExecute(claimsAttribute);
}
private bool CanExecute(ClaimsPrincipalPermissionAttribute claimsAttribute)
{
if (claimsAttribute == null)
return true;
try
{
claimsAttribute.CreatePermission().Demand();
}
catch (SecurityException)
{
return false;
}
return true;
}
I'm using a SQLite database in a Windows 8 Store Application.
Furthermore I use the SQLite wrapper sqlite-net to do operations on the database.
I will explain this in detail so that you understand my situation.
There are Model classes that contain the business logic, for example the class Location. Then there are DatabaseModels from which the Database Tables are generated, for example LocationDb.
I don't want to implement the basic database methods like Insert(Model model), Update(Model model), Delete(int id), GetAllRecords() and GetRecord(int id) in every Model class. Instead I want to implement these methods in a base class of all models. This base class of all models is called ModelBase; the base class of all database Models is DbModelBase.
There is no problem implementing the Insert method as follows for all models:
public int Insert(ModelBase model)
{
int id;
using (var db = new SQLite.SQLiteConnection(MainApplication.DBPath))
{
db.Insert(model.GetDbModelFromModel());
id = (int)SQLite3.LastInsertRowid(db.Handle);
}
return id;
}
But I don't know how to implement the other ones using sqlite-net.
I need to find a specific data record in a specific table. I have a model object which contains the id. But how to make one method work with all model classes without explicitly calling the specific table?
The following code works for a single specific database table...
using (var db = new SQLite.SQLiteConnection(MainApplication.DBPath))
{
var queryResult = db.Table<LocationDb>().Where(l => l.Id == model.Id);
if (queryResult.Count() == 1)
{
db.Update(new TeacherDb(model));
}
}
... but I can not write
var queryResult = db.Table<typeof(databaseModel)>().Where(t => t.Id == model.Id);
Write a generic function for that.
What about this solution:
public class BaseModel<T> where T : Type
{
protected T Id;
/// <summary>
/// Adds a new record to data base. It doesn't check for record existance.
/// </summary>
/// <returns></returns>
protected BaseModel<T> Add()
{
try
{
var entities = Variable.CurrentEntities;
var dbSet = entities.Set<BaseModel<T>>();
var result = dbSet.Add(this);
entities.SaveChanges();
return result;
}
catch (Exception exception)
{
LogException.HandleException(exception);
return null;
}
}
protected bool Update()
{
try
{
var entities = Variable.CurrentEntities;
var dbSet = entities.Set<BaseModel<T>>();
var original = dbSet.Find(this);
entities.Entry(original).CurrentValues.SetValues(this);
entities.SaveChanges();
return true;
}
catch (Exception exception)
{
LogException.HandleException(exception);
return false;
}
}
protected BaseModel<T> Delete()
{
try
{
var entities = Variable.CurrentEntities;
var dbSet = entities.Set<BaseModel<T>>();
var result = dbSet.Remove(this);
entities.SaveChanges();
return result;
}
catch (Exception exception)
{
LogException.HandleException(exception);
return null;
}
}
protected bool Upsert()
{
try
{
var entities = Variable.CurrentEntities;
var dbSet = entities.Set<BaseModel<T>>();
dbSet.AddOrUpdate(this);
return true;
}
catch (Exception exception)
{
LogException.HandleException(exception);
return false;
}
}
protected BaseModel<T> Save()
{
try
{
var entities = Variable.CurrentEntities;
var dbSet = entities.Set<BaseModel<T>>();
var original = dbSet.Find(Id);
if (original == null)
{
original = dbSet.Add(this);
}
else
{
entities.Entry(original).CurrentValues.SetValues(this);
}
entities.SaveChanges();
return original;
}
catch (Exception exception)
{
LogException.HandleException(exception);
return null;
}
}
}