Update an entire record using entity framework - c#

I have a working code here.
using (var db = new MyContextDB())
{
var result = db.Books.SingleOrDefault(b => b.BookNumber == bookNumber);
if (result != null)
{
result.MyColumnName= "Some new value";
db.SaveChanges();
}
}
But I have many properties to change. So I was trying for something like
result= newResult;
db.SaveChanges();
But this is not working. Is there any idea to replace a record with a new one?

I think, you can not do this so easily.
You should create a method in your Book class, where you change all of the properties.
result.Update(Book newProperties);
db.SaveChanges();
or
result.Update(string prop1, int prop2, etc.);
db.SaveChanges();

I would recommend to use Automapper. You can use it like this:
var result = db.Books.SingleOrDefault(b => b.BookNumber == bookNumber);
if (result != null)
{
Mapper.Map(newResult, result);
db.SaveChanges();
}
Notice, that probably you will need to properly configure Automapper(e.g. to ignore Id properties when updating)

Related

Entity Framework SaveChanges is called but its not working

I have the following code. When I trace the code I see that City is not null, it's values changes then SaveChanges is called but changes are not saved. there are about hundreds of similar code in this project and all of them works. what the problem can be here?
using (Entities db = new Entities())
{
long id = (long)((string)data.data[i].id).ParseLong();
City city = db.Cities.FirstOrDefault(c => c.Id == id);
if (city != null)
{
city.FromLat = data.data[i].fromlat;
city.ToLat = data.data[i].tolat;
city.FromLng = data.data[i].fromlng;
city.ToLng = data.data[i].tolng;
if (city.FromLat > city.ToLat) More.Swap(ref city.ToLat, ref city.FromLat);
if (city.FromLng > city.ToLng) More.Swap(ref city.FromLng, ref city.ToLng);
db.SaveChanges();
}
}
You haven't provided your model, but using the ref keyword in these lines:
if (city.FromLat > city.ToLat) More.Swap(ref city.ToLat, ref city.FromLat);
if (city.FromLng > city.ToLng) More.Swap(ref city.FromLng, ref city.ToLng);
clearly indicates that FromLat, ToLat, FromLng and ToLng members are fields, thus not mapped to database columns. Make them properties and use different code for swapping (a bit longer, but working):
if (city.FromLat > city.ToLat) { var temp = city.FromLat; city.FromLat = city.ToLat; city.ToLat = temp; };
if (city.FromLng > city.ToLng) { var temp = city.FromLng; city.FromLng = city.ToLng; city.ToLng = temp; };
db.Entry(city).State = EntityState.Modified;
Should do the trick.
Add this right before savechanges
Try setting the state to modified via
db.Entry(city).State = System.Data.Entity.EntityState.Modified;
Or you can manually set each field that has changed as modified.
You did not add the item to its collection (db.Cities.Add(city)).
If you want to update the entity:
db.Entry(city).State = EntityState.Modified;
db.SaveChanges();

Cannot update lead record in CRM?

My code does not seem to be updating the Lead entity. I have created a new Lead(); as you can see in the code and there is no update when I save the record. Is there something I am doing wrong? This way of updating is just as sufficient as updating by doing crmContext.UpdateObject(oLead); crmContext.SaveChanges();. Can someone please help me with why this is not updating the lead? There is a similar question that just refers to the basic plugin but instead of create I am updating.
private List<Product> GetSectionAProducts()
{
List<Product> products = new List<Product>();
var QEproduct = new QueryExpression("product");
// Add all columns to QEproduct.ColumnSet
QEproduct.ColumnSet.AllColumns = true;
// Define filter QEproduct.Criteria
QEproduct.Criteria.AddCondition("productnumber", ConditionOperator.BeginsWith, "MGIP");
var QEproduct_Criteria_0 = new FilterExpression();
QEproduct.Criteria.AddFilter(QEproduct_Criteria_0);
// Define filter QEproduct_Criteria_0
QEproduct_Criteria_0.AddCondition("capg_billingtimeframe", ConditionOperator.Equal, (int)capg_billingcycletype.Monthly);
QEproduct_Criteria_0.AddCondition("capg_mincriteria", ConditionOperator.NotNull);
QEproduct_Criteria_0.AddCondition("capg_maxcriteria", ConditionOperator.NotNull);
QEproduct_Criteria_0.AddCondition("price", ConditionOperator.NotNull);
EntityCollection results = this.OrganizationService.RetrieveMultiple(QEproduct);
if (results.Entities != null)
{
// Retrieve all records from the result set.
foreach (Entity product in results.Entities)
{
products.Add(new Product { Id = product.Id, capg_MinCriteria = (int?)product.Attributes["capg_mincriteria"], capg_MaxCriteria = (int?)product.Attributes["capg_maxcriteria"], Price = (Money)product.Attributes["price"] });
}
}
return products;
}
var duesproduct = sectionA.Where(o => o.capg_MinCriteria.Value <= dues).ToList().OrderByDescending(o => o.capg_MaxCriteria).FirstOrDefault();
if (duesproduct != null)
{
Xrm.Lead oLead = new Lead();
oLead.Id = this.InputTargetEntity.Id;
oLead.capg_CalculatedDuesBilling = new Money(duesproduct.Price == null ? 0 : duesproduct.Price.Value);
if (duesproduct.capg_MaxCriteria <= 100000)
{
oLead.capg_CalculatedDuesBilling = new Money(Math.Round((duesproduct.Price == null ? 0 : duesproduct.Price.Value) * new decimal(0.0290), 2));
}
if (duesproduct.capg_MaxCriteria <= 235000)
{
oLead.capg_CalculatedDuesBilling = new Money(Math.Round((duesproduct.Price == null ? 0 : duesproduct.Price.Value) * new decimal(0.0262), 2));
}
this.OrganizationService.Update(oLead);
}
I highly recommend you updating records with the IOrganizationService.Update directly, not the context. Context is handy for queries, because you can use LINQ, but when you update entities via the context those might be sent to CRM as an update with all the entity attributes you selected, and that could cause weird behaviors because might trigger unexpected workflows. It also fills the Audit History really quickly.
It is much better to create a new instance of a lead, and populate it with the attributes and Id you want to update, only, and call service.Update.

How can I edit or add to a particular field without pull the all object

How I can do just this ( a.myFavorits.Add()) without pulling the all object to var a , because a has a lot of data, and I don't want to pull all a object, but I can't find a way do do it.
I want to do the lambada and the linq without return something but linq is always return something
public static void addFavorits(long f,long idUser)
{
using (var db = dataBase())
{
// here i pull object user from users table
var a = db.users.Where(c => c.id == idUser).SingleOrDefault();
// here i adding to the object field myFavorits new value
//myFavorits is also a table of entitys that connected to user object
a.myFavorits.Add(new BE.FavoritsUsersLong { myLong = f });
db.SaveChanges();
}
}
I thought to do something like this but i dont know how to set the field users_TableId that is the key that connect the 2 tables
public static void addFavorits(long favoritId,long idUser)
{
using (var db = dataBase())
{
db.favoritsUsersLong.Add(new BE.FavoritsUsersLong {myLong = favoritId}
/*,users_TableId =idUser*/);
db.SaveChanges();
}
}
Here's a concrete example that does what you want. In this example, only the Name of a Company is modified and saved. Or an item is added to one of its collections.
var cmp = new Company{ CmpId = 1, Name = "Cmp1" }; // CmpId is the primary key
db.Companies.Attach(cmp);
db.Entry(cmp).Property(c => c.Name).IsModified = true;
// Or add an entity to a collection:
cmp.Users = new[] {new User { Name = "a1", PassWord = "a1" } };
try
{
db.Configuration.ValidateOnSaveEnabled = false;
db.SaveChanges();
}
finally
{
db.Configuration.ValidateOnSaveEnabled = true;
}
Result in SQL:
DECLARE #0 VarChar(30) = 'Cmp1'
DECLARE #1 Int = 1
UPDATE [dbo].[Company]
SET [Name] = #0
WHERE ([CmpId] = #1)
There are a few things to note here:
Obviously you need to know the Id of the entity you want to modify.
The object you create is called a stub entity, which is an incomplete entity. When you try to save such an entity, EF is very likely to complain about null values in required properties. That's why almost certain you'd have to disable validation (temporarily, or, better, dispose the context immediately).
If you want to add an item to a collection, you should leave validation enabled, because you'd want to know for sure that the new entity is valid. So you shouldn't mix these two ways to use a stub entity.
If you often need roughly the same small part of your entity you may consider table splitting.
I'm guessing this is what you want? I don't see you 'editting' I only see you adding.
using (var db = dataBase())
{
var a = new user();
....
//set properties etc..
...
a.myFavorits.Add(new BE.FavoritsUsersLong { myLong = f });
db.users.Add(a);
db.SaveChanges();
}

how to avoid recording redundant data with MVC

I have a class with two properties (name,family).
I have written code for insert into database without problems, but I don't know how to write the code to check if the data already exists?
I need sample for MVC 4 or higher.
Thanks in advance.
public ActionResult Create([Bind(Include="Name,Description")] ColorApplication colorapplication)
{
if (ModelState.IsValid)
{
db.ColorApplications.Add(colorapplication);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(colorapplication);
}
If you wanna use the DbSet, there are the Remove() or RemoveRange() options.
You can eighter remove one:
using (PersonContext db = new PersonContext())
{
Person person = db.Persons.Where(t => t.Name == "My Name").FirstOrDefault<Person>();
db.Persons.Remove(person);
db.SaveChanges();
}
Or give a list of entities that you want to remove:
using (PersonContext db = new PersonContext())
{
List<Person> persons = db.Persons.Where(t => t.Name == "My Name").ToList();
db.Persons.RemoveRange(persons);
db.SaveChanges();
}
You can also use raw SQL statements if you need something more specific:
DELETE FROM PERSON WHERE NAME = 'My Name'

Add to exisiting Database instance from MVC Controller

Private BookingDB db = new BookingDB();
Private MonthDb mdb = new MonthDB();
if (ModelState.IsValid)
{
String date = (booking.Start_Date).ToString();
var check = from b in mdb.months
where b.BookedDays.Contains(date)
select b;
if (check != null)
{
return View(booking);
}
else
{
booking.Reservation_Owner = User.Identity.Name;
//Add booking.Start_Date to mdb.Entry(check).BookedDays
mdb.SaveChanges();
db.bookings.Add(booking);
db.SaveChanges();
return RedirectToAction("Index");
}
}
I've got this code that on creation of a new booking, will check that no exisiting bookings have already been made on or around that specific day.
if the day to be booked is not already been booked (ie exists under BookedDays in mdb.months) then i wish to add the Start_Date of the booking, to the BookedDays string in the mdb.months database (the mdb.month database is just a list of the 12 months)
at first i tried using mdb.Entry() to add to that specific month instance, however i cannot get it to work.
the error is:
the model does not have a definition for BookedDays
what do?
Your checking that check is null
if (check != null)
{
return View(booking);
}
else
{
and then using check anyway:
check.BookedDays
check is null and therefore does not contain any BookedDays. I'm guessing your null check is the wrong way around and should be
if (check == null)
{
return View(booking);
}
else
{
That said your problem is not well explained so I'm not sure.

Categories

Resources