ASP.NET & SQL Server: won't update but will append/insert - asp.net

I am using a database-first approach with a custom html helper to get a state of a checkbox using ajax (without using form in the view). I have two tables:
Tbl_1 -> Id, state (true or false), name (name of checkbox)
Tbl_2 -> Id, user_guid, timestamp, Tbl_1Id (foreign_key)
When I do insert operations, it does without any problem but when I try to update it (based upon the logged in user as it also gets GUID, the table gets appended/inserted with new data).
My controller:
public ActionResult SetState(checkboxstate cbstate)
{
var UserId = new Guid(System.Security.Claims.ClaimsPrincipal.Current.FindFirst("sub").Value);
var ent = new StartopDatabaseEntities();
var cbs = ent.checkboxstates.Where(w => w.Name == "World").FirstOrDefault();
if (cbs == null) // when there are no records in the database
{
ent.checkboxstates.Add(cbstate);
ent.checkboxstateUpdates.SingleOrDefault(c => c.Id == cbstate.Id);
var cbsOp = new checkboxstateUpdates();
cbsOp.timestamp = DateTime.Now;
cbsOp.user_guid = UserId;
cbstate.checkboxstateUpdates.Add(cbsOp);
ent.SaveChanges();
} // record in database, update (I've only one user now, so has to update only this one)
else
{
var cbsOp = new checkboxstateUpdates(); // declare in global
var chc = new checkboxstate(); // to be declared in global
var newCbs = ent.checkboxstateUpdates.Include(c => c.checkboxstate).ToList();
foreach (var u in newCbs)
{
if(u.user_guid==UserId && u.CheckboxStateId == u.checkboxstate.Id)
{
chc.state = cbstate.state;
chc.name = cbstate.name;
ent.checkboxstates.Add(chc);
cbsOp.Tidspunkt = DateTime.Now;
cbsOp.OpdateretAfBruger = UserId;
ent.checkboxstateUpdates.Add(cbsOp);
ent.SaveChanges();
}
}
}
Can anyone explain please why it's not updating but appending/inserting same data with a new Id (primary key)? I have a simple view where Ajax sends a call to the controller with the state and name of the checkbox. I have also tried
Db.Entry(obj).state = EntityState.Modified
without any help

You have not written the code for the logic which want to achieve..
I am not clear on the logic of if block also but the else part can be fixed as following.
var newCbs = ent.checkboxstateUpdates.Include(c => c.checkboxstate).Where(u.user_guid == UserId).FirstOrDefault();
if(newCbs != null) {
newCbs.checkboxstate.state = cbstate.state;
newCbs.checkboxstate.name = cbstate.name;
newCbs.Tidspunkt = DateTime.Now;
newCbs.OpdateretAfBruger = UserId;
ent.SaveChanges();
}

Solved this with the help from #David & #Chetan:
I did some modify in the code as per David:
u.checkboxstate.state=cbstate.state;
u.checkboxstate.name=cbstate.name;
u.timestamp=DateTime.Now;
ent.saveChanges();
I was using the wrong logic i.e. getting instance of the class rather than the 'ent' object. Thanks guys for the help.

Related

Razor, ASP.NET Core, Entity Framework : updating some fields

I'm trying to update two entities at the same time but the change is not applying and I think that when I try to return the update entity it doesn't even found it.
Here is my Razor view:
public IActionResult OnPost()
{
if (!ModelState.IsValid)
{
return Page();
}
repositorioFamiliar.Actualizar(Familiar);
return RedirectToPage("/Familiares/DetalleFamiliar", new { IdPaciente = Familiar.IdPaciente });
}
Here is my update function:
public FamiliaresPer Actualizar(FamiliaresPer familiar)
{
var familiarActualizar = (from f in _context.Familiars.Where(p => p.IdFamiliar == familiar.IdFamiliar) select f).FirstOrDefault();
if (familiarActualizar != null)
{
familiarActualizar.Correo = familiar.Correo;
_context.Update(familiarActualizar);
_context.SaveChanges();
}
var personaActualizar = (from p in _context.Personas.Where(p => p.Id == familiar.IdPersona) select p).FirstOrDefault();
if (personaActualizar != null)
{
personaActualizar.Telefono = familiar.Telefono;
_context.Update(personaActualizar);
_context.SaveChanges();
}
var familiares = from p in _context.Familiars
from p1 in _context.Personas
where p.IdPaciente == familiar.IdPaciente
where p.IdPersona == p1.IdPersona
select new FamiliaresPer()
{
IdFamiliar = p.IdFamiliar,
IdPaciente = p.IdPaciente,
IdPersona = p1.IdPersona,
Id = p1.Id,
Nombres = p1.Nombres,
Apellidos = p1.Apellidos,
Genero = p1.Genero,
Telefono = p1.Telefono,
Parentesco = p.Parentesco,
Correo = p.Correo,
};
FamiliaresPer familiaresPer = familiares.FirstOrDefault();
return familiaresPer;
}
When I submit the form I get an error
NullReferenceException: Object reference not set to an instance of an object
And the link shows the IdPaciente = 0 when it should use the same IdPaciente of the updated entity (which the Id never changes).
In your OnPost( ) Action Method, you used repositorioFamiliar.Actualizar(Familiar);
but it looks like you didn't define 'Familiar'.
In addition, when I look at your code. I can give you an advice. Let's say your first update was done correctly and you got an error in the second update case. But you want both to be updated at the same time. Assume that the first object is updated in the database but the second one isn't. This is a problem, right? Unit of Work design pattern is very useful to solve this.
In brief, The approach should be to do SaveChanges() after both update processes are completed so there will be no changes in the database until both updates are completed.

ASP.NET Entity Framework request SQL

I need to write this SQL statement in Entity Framework:
SELECT
SALARIE.MATRICULE, LIEU, UO, UO_RATTACHEMENT,
PHOTO.PHOTO, SALARIE.NOM, SALARIE.PRENOM
FROM
SALARIE, UNITE_ORG, PHOTO
WHERE
SALARIE.LIEU = UNITE_ORG.UO
I use this method for reading my data :
public JsonResult Read()
{
var nodes = entities.UNITE_ORG.Select(p => new NodeModel { id = p.UO, pid = p.UO_RATTACHEMENT, poste = p.POSTE, img=p.LIB_COMPLET, Fullname=p.RESPONSABLE });
return Json(new { nodes = nodes }, JsonRequestBehavior.AllowGet);
}
I need to change this declaration of nodes.
Thank you
I believe that the equivalent Entity Framework would be the following:
var result = (from s in context.SALARIE
from u in context.UNITE_ORG
from p in context.PHOTO
where s.LIEU == u.UO
select new {
MATRICULE = s.MATRICULE,
LIEU = s.LIEU,
UO = u.UO,
UO_RATTACHEMENT = UO_RATTACHEMENT, // I don't know where this is coming from
PHOTO = p.PHOTO,
NOM = s.NOM,
PRENOM = s.PRENOM
}
);
However, this is just a guess from the information you have giving.
Also, like I have stated in my comment, I really think you should stop using the syntax for cross joins that you are doing (the , seperated syntax)

push data from web form into CRM 2015 with duplicate detection before creating new records inside CRM

Guys.
I have a web form to push metadata into CRM 2015 online by creating new records. But before creating new records in CRM, I would like to check if this records(First Name, Last Name, DOB) duplicate or not. If duplicates, updates the existing record, If not, create a new record.
My current idea is, that on the web form(ASP.NET APP) retrieve all records(Names, DOB) and compare with input metadata, if match, updates or creates new record. But I am not sure if there is simple way to do this.
Do you have any suggestion?
Appreciate it.
I think I just got it.
bool hasDulicate = false;
//duplicate detection
FilterExpression codeFilter = new FilterExpression(LogicalOperator.And);
codeFilter.AddCondition("firstname", ConditionOperator.Equal, firstname.Text);
codeFilter.AddCondition("lastname", ConditionOperator.Equal, lastname.Text);
QueryExpression query = new QueryExpression
{
EntityName = "contact",
ColumnSet = new ColumnSet(true), // we assume you want to retrieve all the fields
Criteria = codeFilter
};
EntityCollection records = service.RetrieveMultiple(query);
int totalrecords = records.Entities.Count;
foreach (Entity record in records.Entities)
{
if (record["emailaddress1"] != null)
{
record["emailaddress1"] = email.Text;
record["mobilephone"] = phone.Text;
proxy.Update(record);
hasDulicate = true;
}
}
if (hasDulicate == false)
{
Entity contact = new Entity("contact");
contact["firstname"] = Convert.ToString(firstname.Text);
contact["lastname"] = Convert.ToString(lastname.Text);
contact["emailaddress1"] = Convert.ToString(email.Text);
contact["mobilephone"] = Convert.ToString(phone.Text);
Guid conid = proxy.Create(contact);
}

Is this an inefficient way to compare data across multiple tables?

I am using the following code to first check if a string is located somewhere within a column in my database. If it is, I am then needing to check if a few additional criteria are met by looking at different parts of the database (can be seen in the code below). I am not sure if this is an efficient method for doing this or if there is a much simpler way:
(from my Controller)
[HttpPost]
public ActionResult Index(FormCollection sampleKey)
{
string code = sampleKey["sampleCode"];
ViewBag.code = code;
// Need to check if this code is active
var order = db.Orders.SingleOrDefault(
o => o.OrderCode == code
&& o.Active == true);
if (order == null)
{
//Invalid
}
else
{
var orderIdent = db.OrderDetails.SingleOrDefault(
p => p.OrderDetailId == order.OrderId);
var barIdent = db.Drink.SingleOrDefault(
q => q.EstablishmentsID == orderIdent.DrinksId);
var barName = db.Establishment.SingleOrDefault(
r => r.EstablishmentsId == barIdent.EstablishmentsID);
ViewBag.barId = barName.name;
ViewBag.sample = order.Email;
var custProfile = CustomProfile.GetUserProfile();
if (custProfile.OwnedBar != barName.name)
{
//Not a match
}
else
{
//Match
}
}
return View();
}
Is this something to worry about? Is there a more efficient way of performing the actions that I am currently performing? Should I change the first table that is referenced to include data from the table I ultimately compare it to to avoid what seems to be an inefficient way of comparing information from different tables?
You should check the SQL query that gets generated. You can do that by e.g. outputting the queries to the console, which is done by setting db.Log = Console.Out;. There should be a similar method to output to the web page in your case. The lazy nature of LINQ makes things difficult to predict.
Other than that, you could make your life much easier if you create foreign key relationships between your tables, i.e. OrderDetails has Orders.OrderId as a FK. This will allow Entity Framework to generate navigational properties for your database. With them your code would look like this:
[HttpPost]
public ActionResult Index(FormCollection sampleKey)
{
string code = sampleKey["sampleCode"];
var detail = db.Orders.Where(o => o.OrderCode == code && o.Active == true)
.Select(o => new {
OrderCode = o.OrderCode,
BarId = o.Drink.Establishment.Select(n => n.name),
Sample = o.Email
})
.SingleOrDefault();
if (detail != null)
{
ViewBag.code = detail.OrderCode;
ViewBag.barId = detail.BarId;
ViewBag.sample = detail.Sample;
var custProfile = CustomProfile.GetUserProfile();
if (custProfile.OwnedBar == detail.BarId)
{
//Match
}
else
{
//Not a match
}
}
else
{
//Invalid
}
return View();
}

Searching for a string in a single column in a table within an ASP.NET MVC application

I have a table named Orders that has a column named OrderCode that stores a string that I randomly generate at the time of creation.
I want to make sure this string (OrderCode) is unique before I save it to my table.
How I have attempted to do this:
bool isUnique = false;
var order = new Order();
var code = RandomCode.Generate();
while (isUnique == false) // checks to see if the code we generated is unique among all generated codes, if not, will generate another code
{
var activeOrders = storeDB.Orders.Find("OrderCode", code);
if (activeOrders == null)
{
isUnique = true;
}
else
{
code = RandomCode.Generate();
}
}
order.OrderCode = code;
The problem appears to be that the DbSet<TEntity>.Find Method is actually used to search through primary keys - but I am needing to search for a string that is not a primary key.
What is a correct approach to this situation?
if (context.Orders.Any(o => o.OrderCode == code))
{
// key found
}
if (context.Orders.FirstOrDefault(o => o.OrderCode == code) != null)
{
// key found
}
May I ask why you don't just use a System.Guid though (Guid.NewGuid().ToString())? This would virtually eliminate this kind of issue.

Resources