Update not reflected in table - c#

This is my action method has been defined in Home controller for updating row
[HttpPost]
public ActionResult UpdateISRCEntry(ABC.Models.tbl1 z, List<string> verticall,string Album, string Song)
{
if (Session["user"] != null)
{
if (verticall != null)
{
foreach (string s1 in verticall)
{
if (s1 == "Radio")
{ z.Radio = "Radio"; }
if (s1 == "Online")
{ z.Online = "Online"; }
if (s1 == "Mobile")
{ z.Mobile = "Mobile"; }
}
}
tbl1.Service.Class1.updatetbl1(z, Album, Song);
return RedirectToAction("Home");
}
else
{
return RedirectToAction("Index");
}
}
and below is my method has been implemented in class1 to implement updatable row
public static bool updatetbl1(tbl1 obj, string Album, string Song)
{
ABC.Models.tbl1 objmain = new Models.mainISRC();
using (ABCManagementDBEntities1 dbcontect = new ABCManagementDBEntities1())
{
var zz = (from z in dbcontect.tbl1
where z.Album == Album && z.Song == Song select z
).SingleOrDefault();
objmain.Mood = obj.Mood;
objmain.Online = obj.Online;
objmain.Radio = obj.Radio;
dbcontect.SaveChanges();
return true;
}
return false;
}
All these codes are running successfully but the update is not reflected in my table for that row. However, during running my code no any kind of error is arise. Please help someone.

Add this before dbcontect.SaveChanges();
dbcontect.Entry(objmain).State = EntityState.Modified;
dbcontect.SaveChanges();
or I think just this will do
this.UpdateModel(objmain);
dbcontect.SaveChanges();
You should update entity before SaveChanges()

Why are you pulling the zz object and never use it? The way your wrote your "updatetbl1" method, you are inserting a new object (objmain) to the database instead of updating the zz object. Am I assuming correct here?
I think it should be like this:
public static bool updatetbl1(tbl1 obj, string Album, string Song)
{
ABC.Models.tbl1 objmain = new Models.mainISRC();
using (ABCManagementDBEntities1 dbcontect = new ABCManagementDBEntities1())
{
var zz = (from z in dbcontect.tbl1
where z.Album == Album && z.Song == Song select z
).SingleOrDefault();
zz.Mood = obj.Mood;
zz.Online = obj.Online;
zz.Radio = obj.Radio;
dbcontect.Entry(zz).State = EntityState.Modified;
dbcontect.SaveChanges();
return true;
}
return false;
}

Related

How to handle New transaction is not allowed because there are other threads running in the session for multiple calls or to save as list of Entities

Hi I am using Entity Framework Code First, I have a collection of Entities that need to be saved, but I have my EF Repository created as below
public T Create(T item)
{
try
{
if (ufb != null && ufb.CurrentUser != null)
{
SetValue("CreatedByUserId", item, ufb.CurrentUser.Id);
SetValue("UpdatedByUserId", item, ufb.CurrentUser.Id);
}
SetValue("DateCreated", item, DateTime.Now);
SetValue("DateUpdated", item, DateTime.Now);
var newEntry = this.DbSet.Add(item);
this.Context.Database.Log = message => LogHandler.LogInfo(1111, message);
try
{
this.Context.SaveChanges();
}
catch (Exception ex)
{
LogHandler.LogInfo(2501, ex.Message);
}
BuildMetaData(item, true, true);
return newEntry;
}
catch (DbEntityValidationException dbEx)
{
// http://forums.asp.net/t/2014382.aspx?Validation+failed+for+one+or+more+entities+See+EntityValidationErrors+property+for+more+details+
string msg = string.Empty;
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
msg += validationError.PropertyName;
msg += "---";
msg += validationError.ErrorMessage;
msg += "||";
}
}
throw new Exception("7777 CREATE EntityValidationErrors: " + msg);
}
}
My calling method is as below:
public List<VehicleInfo> Create(List<VehicleInfo> vehicleInfos, string Entity, int EntityId)
{
bool vehicleExists = false; List<VehicleInfo> newVehicleInfos = null;
if ((vehicleInfos != null) && (vehicleInfos.Count > 0))
{
newVehicleInfos = new List<VehicleInfo>();
foreach (VehicleInfo vehicleInfo in vehicleInfos)
{
vehicleExists = false;
if (vehicleInfo != null)
{
vehicleExists = this.VehicleExists(vehicleInfo.VehicleId, Entity, EntityId);
vehicleInfo.Entity = Entity;
vehicleInfo.EntityId = EntityId;
VehicleInfo v = this.UnitOfWork.VehicleInfoRepository.Create(vehicleInfo);
newVehicleInfos.Add(v);
}
}
}
return newVehicleInfos;
}
Hence when I am calling repositories create method for multiple times, its throwing me the above error, any help or suggestion would be very helpful, please thank you.
void BuildMetaDataNoThread(object item, bool active, bool isNew = false)
{
if (item.GetType() != typeof(JsonObject))
{
var dm = new DataAccessUnitOfWork(Constants.DefaultConnection);
var qtype = item.GetType();
if (qtype.BaseType.BaseType != null)
{
if ((isNew && qtype.BaseType.Name == typeof(ModelBase).Name) | qtype.BaseType.BaseType.Name == typeof(ModelBase).Name)
{
Thread.Sleep(500);
//collect data
var element = (ModelBase)item;
element.BuildMetaData(DataRequestType.CurrentItem);
var records = ModelBase.MetaData;
ModelBase.MetaData = new List<ModelRecord> { };
if (records == null) return;
foreach (ModelRecord r in records)
{
if (r!=null)
{
var jsr = new JavaScriptSerializer();
//object meta = r;
object rdata = r.Data;
var type = rdata.GetType();
var token = type.BaseType.Name;
List<string> include = r.Include;
// Cycle-through clieanup of models to be encoded into Json Data.
// this helper eliminates infinate relations by including records specified
// by a list of strings
if (include.Where(x => x.Contains("CreatedByUser")).Count() == 0)
include.Add("CreatedByUser");
if (include.Where(x => x.Contains("UpdatedByUser")).Count() == 0)
include.Add("UpdatedByUser");
var data = ClassCloner.CollectData(rdata, include);
List<string> tags = ClassCloner.CollectTags(data);
string _tags = "";
tags.ForEach((xtm) =>
{
_tags += xtm + ',';
});
var json = jsr.Serialize(data);
int id = 0;
//get identity
foreach (var prop in type.GetProperties())
{
if (id == 0)
{
foreach (var cp in prop.CustomAttributes)
{
if (cp.AttributeType.Name == "KeyAttribute")
{
var _id = ((Dictionary<string, object>)data)[prop.Name];
id = (int)_id;
break;
}
}
}
else { break; }
}
var query = dm.JsonObjectRepository.GetAll();
var key = "_" + token;
var _data = (Dictionary<string, object>)data;
var ExistingMetaData = (from x in query where x.SourceKey == key && x.SourceId == id select x).FirstOrDefault();
if (ExistingMetaData != null)
{
if (_data.ContainsKey("DateUpdated")) ExistingMetaData.Date = (DateTime)_data["DateUpdated"];
ExistingMetaData.SourceData = data;
ExistingMetaData.Encode();
ExistingMetaData.Active = active;
ExistingMetaData.SearchTags = _tags;
dm.JsonObjectRepository.Update(ExistingMetaData);
}
else
{
var newData = new JsonObject
{
Active = true,
Date = (DateTime)_data["DateUpdated"],
SourceData = data,
SourceId = id,
SourceKey = key,
SearchTags = _tags,
TargetKey = "GlobalSearchMetaData"
};
newData.Encode();
dm.JsonObjectRepository.Create(newData);
}
}
}
}
}
}
}
void BuildMetaData(object dataRecord, bool active, bool isNew)
{
new Thread((item) => { BuildMetaDataNoThread(item, active, isNew); }).Start(dataRecord);
}

Cannot read account number from list

I am trying to read AccountNumber from a text file, but it does not seem to be reading the AccountNumber from the text file, and I can confirm that the text file location string is correct. Also, note that currently the user is only set to access BasicAccountTestRepository class, but I am trying to get the LoadAccounts method to be able to call GetAccounts() from FileAccountRepository.cs. According to my instructions, I should be able to read from the text file in this class. I am getting a NullReferenceException on LoadAccounts method, says "Object reference not set to an instance of an object."
Accounts.txt
AccountNumber,Name,Balance,Type
10001,Free Account,100,F
20002,Basic Account,500,B
30003,Premium Account,1000,P
FileAccountRepository.cs
public class FileAccountRepository : IAccountRepository
{
List<Account> accounts = new List<Account>();
public Account _account = new Account();
public void GetUsers() {
string path = #".\Accounts.txt";
string[] rows = File.ReadAllLines(path);
for (int i = 1; i < rows.Length; i++)
{
string[] columns = rows[i].Split(',');
//Account account = new Account();
_account.AccountNumber = columns[0];
_account.Name = columns[1];
_account.Balance = Decimal.Parse(columns[2]);
if (columns[3] == "F")
{
_account.Type = AccountType.Free;
}
else if (columns[3] == "B")
{
_account.Type = AccountType.Basic;
}
else if (columns[3] == "P")
{
_account.Type = AccountType.Premium;
}
accounts.Add(_account);
}
}
public Account LoadAccount(string AccountNumber)
{
if (accounts.Any(x => x.AccountNumber == AccountNumber))
{
return _account;
}
return null;
}
public void SaveAccount(Account account)
{
_account = account;
}
}
AccountManager.cs
...
public AccountLookupResponse LookupAccount(string accountNumber)
{
AccountLookupResponse response = new AccountLookupResponse();
FileAccountRepository fileAccount = new FileAccountRepository(); //NullReferenceException
fileAccount.GetUsers();
response.Account = _accountRepository.LoadAccount(accountNumber);
if(response.Account == null)
{
response.Success = false;
response.Message = $"{accountNumber} is not a valid account.";
}
else
{
response.Success = true;
}
return response;
}
...
You need to fix the code in your GetUsers. This code is wrong because is adding the same instance to your list. This will end with many entries in your list but for the same Account instance and all of these entries show the same data. The data assigned to the variable _account in the last loop.
You need to have a variable of type Account declared and initialized inside the loop. In this way every entry in the list is a different instance with different data
public class FileAccountRepository : IAccountRepository
{
List<Account> accounts = new List<Account>();
public void GetUsers() {
string path = #".\Accounts.txt";
string[] rows = File.ReadAllLines(path);
for (int i = 1; i < rows.Length; i++)
{
Account data = new Account();
string[] columns = rows[i].Split(',');
data.AccountNumber = columns[0];
data.Name = columns[1];
data.Balance = Decimal.Parse(columns[2]);
if (columns[3] == "F")
{
data.Type = AccountType.Free;
}
else if (columns[3] == "B")
{
data.Type = AccountType.Basic;
}
else if (columns[3] == "P")
{
data.Type = AccountType.Premium;
}
accounts.Add(data);
}
}
Now when you need to find an account by AccountNumber you call the method LoadAccount searching the Account from the list
public Account LoadAccount(string AccountNumber)
{
return accounts.FirstOrDefault(x => x.AccountNumber == AccountNumber);
}
FirstOrDefault will search your list for a matching value according to your lambda expression and return the account found or null.

Count doesn't consider the newly inserted record

After inserting the first record, the count shows 0 even after the insert. I can see the the record inserted as soon as SaveContext()
is executed. So looks like userChangeRequestApprovalRepository isnt refreshed with the newly inserted data.
Is it appropriate to do count + 1 like the statement below instead
userChangeRequestApprovalRepository.Where(x => x.UserChangeRequestId == userChangeRequest.Id).Count() + 1;
Code
InsertUserChangeRequestApproval(userChangeRequest);
SaveContext();
var numberOfAprovals = userChangeRequestApprovalRepository.Where(x => x.UserChangeRequestId == userChangeRequest.Id).Count();
insert method
private void InsertUserChangeRequestApproval(UserChangeRequest userChangeRequest)
{
UserChangeRequestApproval userChangeRequestApproval = new UserChangeRequestApproval()
{
UserChangeRequestId = userChangeRequest.Id,
ApprovedByAuthUserId = userChangeRequest.ChangedByAuthUserId,
ApprovedDateTime = DateTime.Now,
IsActive = true
};
UserChangeRequestApprovalRepository.Insert(userChangeRequestApproval);
}
public virtual void Insert(TEntity entity)
{
_dbSet.Add(entity);
}
SaveContext method
public int SaveContext()
{
return _context.SaveChanges();
}
The code for the whole method
public IdentityResult ApproveUserChangeRequest(UserChangeRequest userChangeRequest, int approvedByAuthUserId, string authApplicationName)
{
var userChangeRequestRepository = UserChangeRequestRepository.GetAllAsList();
var userChangeRequestApprovalRepository = UserChangeRequestApprovalRepository.GetAllAsList();
var appSettingRepository = AppSettingRepository.GetAllAsList();
var clientCompanyContactRepository = ClientCompanyContactRepository.GetAllAsList();
var applicationUserRepo = ApplicationUserRepo.GetAllAsList();
// int approvedByAuthUserID = GetApprovedByUserId(authApplicationName, approvedByAuthUserName);
// Check if UserChangeRequest is still Pending
bool isUserChangeRequestPending = userChangeRequestRepository.Any(x => x.Id == userChangeRequest.Id && x.ChangeStatus == "Pending");
if (isUserChangeRequestPending && approvedByAuthUserId > 0)
{
// Inserting record in the UserChangeRequestApproval table
InsertUserChangeRequestApproval(userChangeRequest);
SaveContext();
using (var userTransaction = Context.Database.BeginTransaction())
{
using (var securityTransaction = _securityContext.Database.BeginTransaction())
{
try
{
//Get the Number of approval required for Internal and External Users
int? internalApprovalsRequired = GetApprovals("InternalUserChangeRequestApprovalsRequired", appSettingRepository);
int? externalApprovalsRequired = GetApprovals("ExternalUserChangeRequestApprovalsRequired", appSettingRepository);
//Get the name of the application the auth user belongs to
var authUserApplicationName = GetApplicationName(userChangeRequest.AuthUserId);
//Get the Number of approvals for the request
var numberOfAprovals = userChangeRequestApprovalRepository.Where(x => x.UserChangeRequestId == userChangeRequest.Id).Count();
//If the number of approvals is equal or greater than the Approvals required then Update AppUser or Contact details
if ((authUserApplicationName == "ArgentexTrader" && numberOfAprovals >= internalApprovalsRequired) || (authUserApplicationName == "ArgentexClient" && numberOfAprovals >= externalApprovalsRequired))
{
//Updating the clientcontact table
UpdateClientContact(userChangeRequest, clientCompanyContactRepository);
//Updating the auth user table
UpdateAuthUser(userChangeRequest);
//Updating the IdentityDB user table
UpdateIdentityDBUser(userChangeRequest, applicationUserRepo);
//Updating the UserChangeRequest table
userChangeRequest.ChangeStatus = "Approved";
UserChangeRequestRepository.Update(userChangeRequest);
SaveContext();
userTransaction.Commit();
securityTransaction.Commit();
return IdentityResult.Success;
}
}
catch (Exception ex)
{
userTransaction.Rollback();
securityTransaction.Rollback();
_logger.Error(ex);
return IdentityResult.Failed(new IdentityError { Description = ex.Message });
}
}
}
}
return null;
}

How to speed up sql creating process

in my app, i create rows to sql table.
int findNewId = Entities.myTable.Where(a => a.Name == txtName.Text).Select(b => b.Id).FirstOrDefault();
for (int i = 0; i < incomingDtbl.Rows.Count; i++)
{
addNew.Id = findNewId;
addNew.Date = Convert.ToDateTime(incomingDtbl.Rows[i].ItemArray[2]);
addNew.Hour = Convert.ToInt32(incomingDtbl.Rows[i].ItemArray[3]);
...
addNew.CreationDate = System.DateTime.Now;
Entities.myTable.Add(addNew);
Entities.SaveChanges();
}
but my incomingDtbl has like 130000 rows, so it takes soooo long.
is there any way to speed this process up?
i cant directly bulk copy the incomingDtbl because it doesnt have newId.
I have faced similar problem as well (Mine were 170,000 rows). Here's my solution:
public bool InsertData(List<MachineInfo> MachineInfo, string flag,int userID)
{
if (MachineInfo != null && flag != string.Empty)
{
List<T> attList = new List<T>();
foreach (var item in MachineInfo)
{
T att = new T()
{
CreatedDate = DateTime.Now,
DateTime = item.DateTimeRecord,
EnrollNumber = item.EnrollNumber.ToString(),
IPFlag = flag,
SyncBy = userID
};
attList.Add(att);
}
try
{
Entities context = null;
try
{
context = new Entities();
context.Configuration.AutoDetectChangesEnabled = false;
int count = 0;
foreach (var entity in attList)
{
++count;
context = AddToContext(context, entity, count, 100, true);
}
context.SaveChanges();
}
finally
{
if (context != null)
context.Dispose();
}
return true;
}
catch (Exception ex)
{
return false;
}
}
return false;
}
private Entities AddToContext(Entities context, T entity, int count, int commitCount, bool recreateContext)
{
context.Set<T>().Add(entity);
if (count % commitCount == 0)
{
context.SaveChanges();
if (recreateContext)
{
context.Dispose();
context = new Entities();
context.Configuration.AutoDetectChangesEnabled = false;
}
}
return context;
}
It performs really fast because it splits the records and also help you validate.
All the best!!!

How to pass string values from Class file to Mvc Controller

Here i'm using Repo Class in that i wrote some Logic.When that Logic success I want to pass that string msg to mvc controller please Help me
Repo.cs
public void validateUser(Auth aut)
{
var xx=aut.Email;
var xr=db.Auths.Where(rr=>rr.Email == xx).FirstOrDefault();
if (xr != null)
{
var x = (from n in db.Auths
where n.Email == xr.Email && n.Password == xr.Password
select n).FirstOrDefault();
if (x != null)
{
var xz = (from n in db.Auths
where n.Email == xr.Email && n.Password == xr.Password && n.Active == aut.Active
select n).FirstOrDefault();
if (xz != null)
{
string Acc = "Your Account Activated....";
}
}
}
else
{string ddd = "Your Account not Activated....";}}
Controller.cs
Repo objrepo = new Repo();
public ActionResult Login(Auth aut)
{
if (ModelState.IsValid)
{
objrepo.validateUser(aut);
ViewBag.Success = "Success.....";
}
else
ViewBag.msg = "Invalid.....";
return View();
}
You could try this:
public string validateUser(Auth aut)
{
string result = "Invalid Email Address ....";
var xx=aut.Email;
var xr=db.Auths.Where(rr=>rr.Email == xx).FirstOrDefault();
if (xr != null)
{
result = "Invalid Password ....";
var x = (from n in db.Auths
where n.Email == xr.Email && n.Password == xr.Password
select n).FirstOrDefault();
if (x != null)
{
result = "Your Account is not Activated ....";
var xz = (from n in db.Auths
where n.Email == xr.Email && n.Password == xr.Password && n.Active == aut.Active
select n).FirstOrDefault();
if (xz != null)
{
result = "Your Account Activated....";
}
}
}
return result;
}
And this:
public ActionResult Login(Auth aut)
{
if (ModelState.IsValid)
{
string result = objrepo.validateUser(aut);
ViewBag.Success = result;
}
return View();
}
Change return type from void to string in validateUser method of repo.cs file.
Return message from method to controller.
i.e.
In controller file
public ActionResult Login(Auth aut)
{
if (ModelState.IsValid)
ViewBag.msg = objrepo.validateUser(aut);
else
ViewBag.msg = "Invalid.....";
return View();
}
Use ViewBag.msg in view file.
Thanks,
Hiral Shah

Categories

Resources