Using LINQ to SQL in WCF I have a update record methods which ATM I manually assign each updated property.
Eg.
public void UpdateMachineRecord(Guid SessionID, int MachineRecordID, MachineRecord machineRecord)
{
if (!ValidSession(SessionID))
return;
using (MMHLINQSQLDataContext database = new MMHLINQSQLDataContext())
{
MachineRecord record = database.MachineRecords.Single(mr => mr.Job.OperationID == MachineRecordID);
record.ChangedBy = UserSession(SessionID).Name;
record.ChangedDate = DateTime.Now.ToString();
record.Date = machineRecord.Date;
record.EDI = machineRecord.EDI;
...
database.SubmitChanges();
}
}
My questions is: Is there a way to update the record using an entire entity?
Eg.
public void UpdateMachineRecord(Guid SessionID, int MachineRecordID, MachineRecord machineRecord)
{
if (!ValidSession(SessionID))
return;
using (MMHLINQSQLDataContext database = new MMHLINQSQLDataContext())
{
MachineRecord record = database.MachineRecords.Single(mr => mr.Job.OperationID == MachineRecordID);
record = machineRecord;
database.SubmitChanges();
}
}
You can do this.
database.MachineRecords.Attach(machineRecord, true);
database.SubmitChanges();
This will attach it as a modified entity (that's what the boolean parameter is for)
Related
I want to update all the records of the table and change the one column value but it is not working for me
What I tried:
public static void UpdateSellerAutoApprovalSettings(bool isSellerAutoApproved)
{
using (var context = GetDbContext())
{
context.SiteGroups
.AddOrUpdate(x => x.IsSellerAutoApproved,
new SiteGroup { IsSellerAutoApproved = isSellerAutoApproved });
context.SaveChanges();
}
}
You can use EntityFrmaework.Plus library like below
context.SiteGroups
.Update(x => new SiteGroup { IsSellerAutoApproved = isSellerAutoApproved });
This will generate a SQL statement and you will not load all records into a application memory.
Just use ForEach extension method:
context.SiteGroups.ForEach(e => e.IsSellerAutoApproved = isSellerAutoApproved);
please check the below approach.
you can use where in between SiteGroups and ForEach if you need conditional Update
public static void UpdateSellerAutoApprovalSettings(bool isSellerAutoApproved)
{
using (var context = GetDbContext())
{
context.SiteGroups
.ForEach( x => x.IsSellerAutoApproved = isSellerAutoApproved )
context.SaveChanges();
}
}
I'm working on ASP.NET Boilerplate. I have the problem where I try to get a record from a table called Buildings and make an update on it. I get the record from database by:
var buildingApp = _buildingsAppService.getBuildingsById(buildingInput);
And after that, I make some changes on the data as follows:
buildingApp.streetName = Request["buildingaddress"];
buildingApp.isInHoush = Convert.ToBoolean(Request["buildingOutput.isInHoush"]);
buildingApp.houshName = Request["HoushName"];
And then copy the buildingApp to another object, which has the same properties, in order to pass the new object to update method as follows:
var updateBuildingInput = new UpdateBuidlingsInput()
{
Id = buildingApp.Id,
buildingID = buildingApp.buildingID,
numOfBuildingUnits = buildingApp.numOfBuildingUnits,
numOfFloors = buildingApp.numOfFloors,
streetName = buildingApp.streetName,
buildingNo = buildingApp.buildingNo,
neighborhoodID = buildingApp.neighborhoodID,
buildingTypeID = buildingApp.buildingTypeID,
GISMAP = buildingApp.GISMAP,
houshProperty = buildingApp.houshProperty,
houshName = buildingApp.houshName,
X = buildingApp.X,
Y = buildingApp.Y,
buildingName = buildingApp.buildingName,
isInHoush = buildingApp.isInHoush,
buildingUsesID = buildingApp.buildingUsesID
};
And the update method is as follows:
_buildingsAppService.update(updateBuildingInput);
The problem is when it executes the previous line, I get the following error:
System.InvalidOperationException: 'Attaching an entity of type 'TaawonMVC.Models.Buildings' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.'
I can see that when I initialize the object updateBuildingInput manually, the update method runs without error. But when it depends on the object obtained from database using buildingApp, the error happens. It seems like the get method gets data from database and keeps holding on to the record from database, and when I try to update the same record, the conflict happens. This is the whole action where all of get and update happens:
public ActionResult UpdateApplication (UpdateApplicationsInput model)
{
var updateApplication = new UpdateApplicationsInput();
updateApplication.buildingId = Convert.ToInt32(Request["buildingnumber"]);
updateApplication.buildingUnitId = Convert.ToInt32(Request["dropDownBuildingUnitApp"]);
//==== get building and unit related to application for update ======
var buildingInput = new GetBuidlingsInput()
{
Id = updateApplication.buildingId
};
var buildingUnitInput = new GetBuildingUnitsInput()
{
Id = updateApplication.buildingUnitId
};
var buildingApp = _buildingsAppService.getBuildingsById(buildingInput);
var buildingUnitApp = _buildingUnitsAppService.GetBuildingUnitsById(buildingUnitInput);
buildingApp.streetName = Request["buildingaddress"];
buildingApp.isInHoush = Convert.ToBoolean(Request["buildingOutput.isInHoush"]);
buildingApp.houshName = Request["HoushName"];
// buildingUnitApp.BuildingId = updateApplication.buildingId;
buildingUnitApp.ResidenceStatus = Request["residentstatus"];
// copy object getBuildingUnitInput to updateBuildingUnitInput
var updateBuildingUnitInput = new UpdateBuildingUnitsInput()
{
BuildingId = buildingUnitApp.BuildingId,
ResidentName = buildingUnitApp.ResidentName,
ResidenceStatus = buildingUnitApp.ResidenceStatus,
NumberOfFamilyMembers = buildingUnitApp.NumberOfFamilyMembers,
Floor = buildingUnitApp.Floor,
UnitContentsIds = buildingUnitApp.UnitContentsIds
};
//============================================
// copy object from getBuildingOutput to updateBuildingInput
var updateBuildingInput = new UpdateBuidlingsInput()
{
Id = buildingApp.Id,
buildingID = buildingApp.buildingID,
numOfBuildingUnits = buildingApp.numOfBuildingUnits,
numOfFloors = buildingApp.numOfFloors,
streetName = buildingApp.streetName,
buildingNo = buildingApp.buildingNo,
neighborhoodID = buildingApp.neighborhoodID,
buildingTypeID = buildingApp.buildingTypeID,
GISMAP = buildingApp.GISMAP,
houshProperty = buildingApp.houshProperty,
houshName = buildingApp.houshName,
X = buildingApp.X,
Y = buildingApp.Y,
buildingName = buildingApp.buildingName,
isInHoush = buildingApp.isInHoush,
buildingUsesID = buildingApp.buildingUsesID
};
//======================================================
updateApplication.Id = Convert.ToInt32(Request["applicationId"]);
updateApplication.fullName = model.fullName;
updateApplication.phoneNumber1 = model.phoneNumber1;
updateApplication.phoneNumber2 = model.phoneNumber2;
updateApplication.isThereFundingOrPreviousRestoration = model.isThereFundingOrPreviousRestoration;
updateApplication.isThereInterestedRepairingEntity = model.isThereInterestedRepairingEntity;
updateApplication.housingSince = model.housingSince;
updateApplication.previousRestorationSource = model.previousRestorationSource;
updateApplication.interestedRepairingEntityName = model.interestedRepairingEntityName;
updateApplication.PropertyOwnerShipId = Convert.ToInt32(Request["PropertyOwnerShip"]);
updateApplication.otherOwnershipType = model.otherOwnershipType;
updateApplication.interventionTypeId = Convert.ToInt32(Request["interventionTypeName"]);
updateApplication.otherRestorationType = model.otherRestorationType;
updateApplication.propertyStatusDescription = model.propertyStatusDescription;
updateApplication.requiredRestoration = model.requiredRestoration;
updateApplication.buildingId = Convert.ToInt32(Request["buildingnumber"]);
updateApplication.buildingUnitId = Convert.ToInt32(Request["dropDownBuildingUnitApp"]);
// ==== get of restoration types which it is multi select drop down list ======
var restorationTypes = Request["example-getting-started"];
string[] restorationTypesSplited = restorationTypes.Split(',');
byte[] restorationTypesArray = new byte[restorationTypesSplited.Length];
for (var i = 0; i < restorationTypesArray.Length; i++)
{
restorationTypesArray[i] = Convert.ToByte(restorationTypesSplited[i]);
}
updateApplication.restorationTypeIds = restorationTypesArray;
// ====== end of RestorationTypes
_buildingsAppService.update(updateBuildingInput);
_applicationsAppService.Update(updateApplication);
// _buildingUnitsAppService.Update(updateBuildingUnitInput);
// ==== get list of applications ==============
var applicationsUpdate = _applicationsAppService.getAllApplications();
var applicationsViewModel = new ApplicationsViewModel()
{
Applications = applicationsUpdate
};
return View("Applications", applicationsViewModel);
}
How ASP.NET Boilerplate template, which I use, makes CRUD Operation to database:
public class BuildingsManager : DomainService, IBuildingsManager
{
private readonly IRepository<Buildings> _repositoryBuildings;
public BuildingsManager(IRepository<Buildings> repositoryBuildings)
{
_repositoryBuildings = repositoryBuildings;
}
// create new building in table buildings .
public async Task<Buildings> create(Buildings entity)
{
var building = _repositoryBuildings.FirstOrDefault(x => x.Id == entity.Id);
if(building!=null)
{
throw new UserFriendlyException("Building is already exist");
}
else
{
return await _repositoryBuildings.InsertAsync(entity);
}
}
// delete a building from buildings table .
public void delete(int id)
{
try
{
var building = _repositoryBuildings.Get(id);
_repositoryBuildings.Delete(building);
}
catch (Exception)
{
throw new UserFriendlyException("Building is not exist");
}
}
public IEnumerable<Buildings> getAllList()
{
return _repositoryBuildings.GetAllIncluding(b => b.BuildingType, n => n.NeighboorHood,u=>u.BuildingUses);
}
public Buildings getBuildingsById(int id)
{
return _repositoryBuildings.Get(id);
}
public void update(Buildings entity)
{
_repositoryBuildings.Update(entity);
}
}
How can I solve this problem? Many thanks for help.
By creating a new entity (updateBuildingInput) with the same primary key as one you have already read in your context, Entity will throw an error when you attempt an operation on the new entity (as you have seen) as it is already tracking an entity with that primary key in the context.
If _buildingsAppService is a DbContext and all you need to do is make some changes to an entity, you can:
Read the entity
Make changes directly to that entity object
Call _buildingsAppService.SaveChanges()
SaveChanges() will:
Saves all changes made in this context to the underlying database.
When getting the record from db you can use .AsNoTracking()
Or if you really need to update an attached entity first locate the attached copy and detach it, then modify and update;
public async Task<bool> UpdateAsync<T>(T entity)
where T : class, IHasId
{
// check if entity is being tracked
var local = _context.Set<T>().Local.FirstOrDefault(x => x.Id.Equals(entity.Id));
// if entity is tracked detach it from context
if (local != null)
_context.Entry<T>(local).State = EntityState.Detached;
_context.Attach(entity).State = EntityState.Modified;
var result = await _context.SaveChangesAsync();
// detach entity if it was not tracked, otherwise it will be kept tracking
if(local == null)
_context.Entry(entity).State = EntityState.Detached;
return result > 0;
}
btw, IHasId is a simple interface to make Id property accessible for generic types;
public interface IHasId {
int Id { get; set; }
}
Use .AsNoTracking():
public class BuildingsManager : DomainService, IBuildingsManager
{
public Buildings getBuildingsById(int id)
{
return _repositoryBuildings.GetAll().AsNoTracking().First(b => b.Id == id);
}
// ...
}
I want to update some of my columns value using entity framework
My code is as follows
public static void UpdateData(string contentMenu, int eid) //Update data in database
{
using (var context = new CmsContext())
{
try
{
var objDataContent = new Content
{
MenuContent = contentMenu,
ModifiedDateTime = DateTime.Now
};
//Code to update only MenuContent and ModifiedDateTime whose id=eid
GetRecords();
}
catch (Exception ex)
{
//
}
}
}
There are lot of answers in S/O but none of them helped me.
I followed https://stackoverflow.com/a/5567616/4701699
How can I update these two columns on the basis of id parameters like MSSQL query
update [CMS Menu].[dbo].[Contents] set MenuContent = 'testing' ,
ModifiedDateTime ='2016-01-02 16:02:15.803' where ContentId=2
You Can Update Your Column Entries by Using Linq:-
Here Are Example Code:-
var data = db.Content.FirstOrDefault(x=>x.ContentId==eID);
data.ModiFiedDateTime = DateTime.Now;
data.MenuContent = contentMenu;
db.SaveChanges();
I have the following method:
public static Int32 SaveAgent(IAgent i)
{
dc = new mcollectorDataContext(ConnectionString.GetConStr());
//check if the record exists
t_agent matchID = dc.t_agents.Where(x => x.id == i.AgentID).FirstOrDefault();
try
{
if (matchID == null)
{
// if not exists add new row
t_agent _agent = new t_agent
{
wallet = i.Wallet,
branchid = GetBranchID(i.Branch),
lastupdated = i.LastUpdated,
};
dc.t_agents.InsertOnSubmit(_agent);
dc.SubmitChanges();
return _agent.id;
}
else
{
// else update row
matchID.wallet = i.Wallet;
matchID.branchid = GetBranchID(i.Branch);
matchID.lastupdated = i.LastUpdated;
dc.SubmitChanges();
return i.AgentID;
}
}
catch (Exception)
{
throw ;
}
}
This method save new reord but when i try to update, it failed, no record can be updated, but it does not throw also an error.
How can fix that problem ??
maybe try telling entity framework that the model has been modified?
try adding this before calling submitchanges
dc.Entry(matchID).State = EntityState.Modified;
To delete all the rows in a table, I am currently doing the following:
context.Entities.DeleteAllOnSubmit(context.Entities);
context.SubmitChanges();
However, this seems to be taking ages. Is there a faster way?
You could do a normal SQL truncate or delete command, using the DataContext.ExecuteCommand method:
context.ExecuteCommand("DELETE FROM Entity");
Or
context.ExecuteCommand("TRUNCATE TABLE Entity");
The way you are deleting is taking long because Linq to SQL generates a DELETE statement for each entity, there are other type-safe approaches to do batch deletes/updates, check the following articles:
Batch Updates and Deletes with LINQ to SQL
LINQ to SQL Extension: Batch Deletion with Lambda Expression
Unfortunately LINQ-to-SQL doesn't execute set based queries very well.
You would assume that
context.Entities.DeleteAllOnSubmit(context.Entities);
context.SubmitChanges();
will translate to something like
DELETE FROM [Entities]
but unfortunately it's more like
DELETE FROM [dbo].[Entities] WHERE ([EntitiesId] = #p0) AND ([Column1] = #p1) ...
DELETE FROM [dbo].[Entities] WHERE ([EntitiesId] = #p0) AND ([Column1] = #p1) ...
DELETE FROM [dbo].[Entities] WHERE ([EntitiesId] = #p0) AND ([Column1] = #p1) ...
You'll find the same when you try to do bulk update in LINQ-to-SQL. Any more than a few hundred rows at a time and it's simply going to be too slow.
If you need to do batch operations & you're using LINQ-to-SQL, you need to write stored procedures.
I like using an Extension Method, per the following:
public static class LinqExtension
{
public static void Truncate<TEntity>(this Table<TEntity> table) where TEntity : class
{
var rowType = table.GetType().GetGenericArguments()[0];
var tableName = table.Context.Mapping.GetTable(rowType).TableName;
var sqlCommand = String.Format("TRUNCATE TABLE {0}", tableName);
table.Context.ExecuteCommand(sqlCommand);
}
}
you could also use this:
Public void BorraFilasTabla()
{
using(basededatos db = new basededatos())
{
var ListaParaBorrar = db.Tabla.Tolist();
db.Tabla.RemoveRange(ListaParaBorrar);
}
}
The Below c# code is used to Insert/Update/Delete/DeleteAll on a database table using LINQ to SQL
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace PracticeApp
{
class PracticeApp
{
public void InsertRecord(string Name, string Dept) {
LinqToSQLDataContext LTDT = new LinqToSQLDataContext();
LINQTOSQL0 L0 = new LINQTOSQL0 { NAME = Name, DEPARTMENT = Dept };
LTDT.LINQTOSQL0s.InsertOnSubmit(L0);
LTDT.SubmitChanges();
}
public void UpdateRecord(int ID, string Name, string Dept)
{
LinqToSQLDataContext LTDT = new LinqToSQLDataContext();
LINQTOSQL0 L0 = (from item in LTDT.LINQTOSQL0s where item.ID == ID select item).FirstOrDefault();
L0.NAME = Name;
L0.DEPARTMENT = Dept;
LTDT.SubmitChanges();
}
public void DeleteRecord(int ID)
{
LinqToSQLDataContext LTDT = new LinqToSQLDataContext();
LINQTOSQL0 L0;
if (ID != 0)
{
L0 = (from item in LTDT.LINQTOSQL0s where item.ID == ID select item).FirstOrDefault();
LTDT.LINQTOSQL0s.DeleteOnSubmit(L0);
}
else
{
IEnumerable<LINQTOSQL0> Data = from item in LTDT.LINQTOSQL0s where item.ID !=0 select item;
LTDT.LINQTOSQL0s.DeleteAllOnSubmit(Data);
}
LTDT.SubmitChanges();
}
static void Main(string[] args) {
Console.Write("* Enter Comma Separated Values to Insert Records\n* To Delete a Record Enter 'Delete' or To Update the Record Enter 'Update' Then Enter the Values\n* Dont Pass ID While Inserting Record.\n* To Delete All Records Pass 0 as Parameter for Delete.\n");
var message = "Successfully Completed";
try
{
PracticeApp pa = new PracticeApp();
var enteredValue = Console.ReadLine();
if (Regex.Split(enteredValue, ",")[0] == "Delete")
{
Console.Write("Delete Operation in Progress...\n");
pa.DeleteRecord(Int32.Parse(Regex.Split(enteredValue, ",")[1]));
}
else if (Regex.Split(enteredValue, ",")[0] == "Update")
{
Console.Write("Update Operation in Progress...\n");
pa.UpdateRecord(Int32.Parse(Regex.Split(enteredValue, ",")[1]), Regex.Split(enteredValue, ",")[2], Regex.Split(enteredValue, ",")[3]);
}
else
{
Console.Write("Insert Operation in Progress...\n");
pa.InsertRecord(Regex.Split(enteredValue, ",")[0], Regex.Split(enteredValue, ",")[1]);
}
}
catch (Exception ex)
{
message = ex.ToString();
}
Console.Write(message);
Console.ReadLine();
}
}
}