Guys I've a EntityModel called mapsModel, which has an entity Type called 'BodyChartNew'
For Inserting records I'm using a Handler called InsertMap, In this handler I'm using the code like as follows:
using System;
using System.Web;
public class InsertMap : IHttpHandler
{
private mapsModel.mapsEntities _dataContext = new mapsModel.mapsEntities();
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
// Extract form fields
var title = context.Request["title"];
var note = context.Request["remarks"];
var referenceID = context.Request["patient_id"];
var diagnosisID = context.Request["diagnosis_id"];
// Create Chart to insert
var mapsToInsert = new mapsModel.BodyChart { MapCode = title, Remarks = note, PatientID = Convert.ToInt32(referenceID), DiagnosisID = Convert.ToInt32(diagnosisID) };
// Save new movie to DB
try
{
_dataContext.AddToBodyChart(mapsToInsert);
_dataContext.SaveChanges();
// Return success
context.Response.Write("success");
}
catch
{
context.Response.Write("fail");
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
I'm calling this Handler from my JQuery Code, This is working fine for me with INSERT, what I need is UPDATE code. What is the UPDATE statement to update the records based on referenceID and diagnosisID ?
Please help me!
You need to bring down the entity from the database (something like
var entity = _dataContext.BodyChart.Single(e => e.PatientID = context.Request["patient_id"]);
modify properties you want to modify and call
_dataContext.SaveChanges()
Related
hi I want to write an update function to check the data in my database and if there was a similar column don't add the filed update that filed
here in the code below, I deserialize JSON file
public class CustomerDeserializer
{
public static List<DtoCustomer> Deserialize()
{
List<DtoCustomer> result =
JsonConvert.DeserializeObject<List<DtoCustomer>>(
File.ReadAllText(#"Information.json"));
return result;
}
}
in this part, I read the data and build it
public static Customer CustomerBuild(DtoCustomer dto)
{
return new Customer()
{
FirstName = dto.FirstName,
LastName = dto.LastName,
Address = dto.Address,
Email = dto.Email,
ComapnyName = dto.CompanyName,
PhoneNumber = dto.Phone
};
and then I process data and save them into database
////update function
public static void Process(Customer customer)
{
using (var context = new PracticeEntities1())
{
context.Customers.Add(customer);
context.SaveChanges();
}
}
I want to write an update function before saving to check the data and update it what should I do?
You may do something like this:
using (var context = new PracticeEntities1())
{
var existingCustomer = context.Customers.FirstOrDefault(c => c.Email == customer.Email);
if (existingCustomer != null) {
existingCustomer.FirstName = customer.FirstName;
existingCustomer.LastName = customer.LastName;
existingCustomer.Address = customer.Address;
existingCustomer.CompanyName = customer.CompanyName;
existingCustomer.Phone = customer.Phone;
}
else
{
context.Customers.Add(customer);
}
context.SaveChanges();
}
I'm making a simple WPF application that uses one table in a DB. I'm using Entity Framework. Here's how I add my new record:
public static bool CreateNew(CustomerModel newCustomer)
{
var addCustomer = new Customer
{
ID = newCustomer.ID,
Name = newCustomer.Name,
Address = newCustomer.Address,
City = newCustomer.City,
Country = newCustomer.Country
};
try
{
//_context.Customers.Add(addCustomer);
_context.Entry(addCustomer).State = EntityState.Added;
_context.SaveChanges();
return true;
}
catch
{
return false;
}
}
Works fine: record appears in DB.
Now I try to delete the record that was just added based on its ID:
public static bool Delete(long id)
{
var cust = new Customer() { ID = id };
try
{
_context.Entry(cust).State = EntityState.Deleted;
/*_context.Customers.Attach(cust);
_context.Customers.Remove(cust);*/
_context.SaveChanges();
return true;
}
catch
{
return false;
}
}
Doesn't work.
It seems like the DbSet within the application does not hold the entry that was added to the DB. How do I fix this?
PS. Customer class is my POCO entity and CustomerModel is the class I use for the application. _context references the DbContext Entity Framework uses
Try this instead. Use Find method like this:
var cust = _context.Customers.Find(id);
_context.Customers.Remove(cust);
_context.SaveChanges();
I've got method AddOrUpdateFruitMetaData which should add or update record in FruitMetaData table.
Unfortunately I'm keep getting an errors:
Violation of PRIMARY KEY constraint 'PK_FruitMetaData'. Cannot insert duplicate key in object 'dbo.FruitMetaData'. The duplicate key value is (0, COLOR). The statement has been terminated.
How this is even possible even when I'm trying to find existing record before?
Also using AddOrUpdate() from System.Data.Entity.Migrations instead of Add() is not helping me.
Call stack looks that:
In my main class in Parallel.ForEach with multiple for loop looking like that:
Parallel.ForEach(args)
{
for(something)
{
var fruit = new Fruit();
fruit.FruitId = uniqueId;
UpdateOrCreateFruitMetaData(fruit, "Color", "Blue")
}
}
I'm calling method:
private void UpdateOrCreateFruitMetaData(Fruit fruit, string metaType, string value)
{
var fruitMetaData = new FruitMetaData();
fruitMetaData.FruitId = fruit.FruitId;
fruitMetaData.MetaType = metaType;
fruitMetaData.Value = value;
using (var db = Context.DB)
{
db.AddOrUpdateFruitMetaData(fruitMetaData);
}
}
That method is using Context.DB which is object containing new DBEntity() and also Dispose(). So my Entity Context is disposed every time.
Then I'm calling next method AddOrUpdateFruitMetaData():
AddOrUpdateFruitMetaData(FruitMetaData fruitMetaData)
{
lock (thisLock)
{
try
{
var fmd = db.FruitMetaData.Where(x => x.FruitId == fruitMetaData.FruitId)
.Where(x => x.MetaType == fruitMetaData.MetaType)
.FirstOrDefault();
if (fmd == null)
db.FruitMetaData.Add(fruitMetaData);
else
fmd.Value = fruitMetaData.Value;
db.SaveChanges();
}
catch (Exception ex)
{
Log.Error($"AddOrUpdateFruitMetaData. FruitId:{fruitMetaData.FruitId} MetaType:{fruitMetaData.MetaType}", ex);
}
}
}
[EDIT] To explain using (var db = Context.DB) :
My Context class contains DbData DB Property which looks like that :
public DbData DB
{
get { return new DbData(); }
}
And DbData class looks like that:
public class DbData : IDisposable
{
private DBEntity db;
public DbData()
{
db = new FruitDBEntity();
}
// This class contains that problematic method
AddOrUpdateFruitMetaData(FruitMetaData fruitMetaData)(...)
}
So each time I'm getting Context.DB property I am actually creating new Entity Context.
I am trying to override SaveChanges DbContect using Entity Framework.
The
override int SaveChanges()
is not running and the break-point is not being hit.
I have moved the class into the root where the EDMX file is located but that still did not help.
How can get I the SaveChanges override to work?
using System;
using System.Data.Entity;
namespace DAL
{
public class MyEntities : DbContext
{
public override int SaveChanges()
{
throw new Exception("override DbContext>SaveChanges working");
// return base.SaveChanges();
}
}
}
Code to call SaveChanges
using (var ctx = new Entities())
{
// model.clientID = data.clientID;
// model.clientGUID = data.clientGUID;
model.clientName = data.clientName;
model.clientDept = data.clientDept;
model.clientWebsite = data.clientWebsite;
model.clientEmail = data.clientEmail;
model.isActive = data.isActive;
model.clientModDate = data.clientModDate;
model.clientCreatedDate = data.clientCreatedDate;
ctx.Clients.Add(model);
ctx.SaveChanges();
}
The easiest way: the EF class is defined with "partial". So add another class file with the class name being:
public partial class MyEntities
{
public void SavingChanges()
{
//Do custom code
this.SaveChanges();
}
}
And change all of your SaveChanges() calls to SavingChanges(). Then you can customize the process however you want. The key is to add another partial class so make sure the EF context has the partial defined (not in your code sample but was the default implementation).
I was able to get the code working using the comments provided.
Create the class file in the same project the EDMX is located
public partial class Entities <--- same name as project Entity
all working now!
https://exceptionnotfound.net/entity-change-tracking-using-dbcontext-in-entity-framework-6/
namespace ModelApp_MVC.Models
{
public partial class Entities : DbContext
{
public override int SaveChanges()
{
//Do custom code
// throw new Exception("override DbContext>SaveChanges working");
// this.SaveChanges();
var modifiedEntities = ChangeTracker.Entries()
.Where(p => p.State == EntityState.Modified).ToList();
var now = DateTime.UtcNow;
foreach (var change in modifiedEntities)
{
var entityName = change.Entity.GetType().Name;
var primaryKey = GetPrimaryKeyValue(change);
foreach (var prop in change.OriginalValues.PropertyNames)
{
var originalValue = change.OriginalValues[prop].ToString();
var currentValue = change.CurrentValues[prop].ToString();
if (originalValue != currentValue) //Only create a log if the value changes
{
ChangeLog log = new ChangeLog()
{
EntityName = entityName,
PrimaryKeyValue = primaryKey.ToString(),
PropertyName = prop,
OldValue = originalValue,
NewValue = currentValue,
DateChanged = now
};
ChangeLogs.Add(log);
}
}
}
return base.SaveChanges();
}
object GetPrimaryKeyValue(DbEntityEntry entry)
{
var objectStateEntry = ((IObjectContextAdapter)this).ObjectContext.ObjectStateManager.GetObjectStateEntry(entry.Entity);
return objectStateEntry.EntityKey.EntityKeyValues[0].Value;
}
}
}
I'm trying to create a trigger to update a document number using the Seed() method in a ContextInitalizer with Entity Framework 6.0.2 and .Net 4. When I run the SQL separately the trigger is created; during context initialization an SqlException is thrown stating:
Incorrect syntax near the word 'TRIGGER'.
My sql script -- contained in /SQL/CreateOrderNumber.sql -- is:
CREATE TRIGGER [dbo].[CreateOrderNum]
ON [dbo].[Orders]
AFTER INSERT AS
BEGIN
SET NOCOUNT ON;
DECLARE #MaximumNumber int;
SET #MaximumNumber = (SELECT ISNULL(MAX(RIGHT([DocNumber],6)),0) FROM [Orders]);
UPDATE [Orders]
SET [DocNumber] = 'ORD-' + RIGHT('000000' + CAST((#MaximumNumber + 1) AS VARCHAR(8)), 6)
FROM inserted
WHERE [Orders].[Id] = inserted.Id;
END
And the following code recreates the error:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Data.SqlClient;
using System.IO;
using System.Reflection;
namespace TriggerCreationTest
{
class Program
{
static void Main(string[] args)
{
// Create the context, add an order, and save...
using (var context = new Context())
{
context.Orders.Add(new Order());
context.SaveChanges();
}
}
}
public class Context : DbContext
{
public Context() : base("TestDatabase")
{
Database.SetInitializer<Context>(new ContextInitializer());
}
public DbSet<Order> Orders { get; set; }
}
public class ContextInitializer : DropCreateDatabaseAlways<Context>
{
protected override void Seed(Context context)
{
// Get the file and read the text
var execPath = Assembly.GetExecutingAssembly().Location;
var createOrderNumPath = Path.Combine(execPath, #"..\SQL\CreateOrderNumber.sql");
var sql = File.ReadAllText(createOrderNumPath);
// Execute the CREATE TRIGGER on the database.
var emptyparams = new SqlParameter[] { new SqlParameter() };
context.Database.ExecuteSqlCommand(sql, emptyparams);
base.Seed(context);
}
}
public class Order
{
public Order() { }
[Key]
public int Id { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public string DocNumber { get; set; }
}
}
At this point I've attempted rewriting the CREATE TRIGGER script according to various sources around the web, but haven't had any success getting it to run.
After having worked around this, and paying attention to other projects, I returned to see whether upgrading to EntityFramework 6.1.0 would make a difference. It did not!
I did, however, find my mistake. I was passing an empty SqlParameter to the SqlCommand and this was causing it to fail. If instead I change the SqlParameter array to contain no elements:
public class ContextInitializer : DropCreateDatabaseAlways<Context>
{
protected override void Seed(Context context)
{
// Get the file and read the text
var execPath = Assembly.GetExecutingAssembly().Location;
var createOrderNumPath = Path.Combine(execPath, #"..\SQL\CreateOrderNumber.sql");
var sql = File.ReadAllText(createOrderNumPath);
// Execute the CREATE TRIGGER on the database.
// CHANGE emptyparams TO CONTAIN NO ELEMENTS
var emptyparams = new SqlParameter[] { };
context.Database.ExecuteSqlCommand(sql, emptyparams);
base.Seed(context);
}
}
The command executes as expected and the trigger is created.