Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Most efficient way to update with LINQ to SQL

Can I update my employee record as given in the function below or do I have to make a query of the employee collection first and then update the data?

public int updateEmployee(App3_EMPLOYEE employee) 
{
    DBContextDataContext db = new DBContextDataContext();
    db.App3_EMPLOYEEs.Attach(employee);
    db.SubmitChanges();
    return employee.PKEY;
}

Or do I have to do the following?

public int updateEmployee(App3_EMPLOYEE employee) 
{
    DBContextDataContext db = new DBContextDataContext();
    App3_EMPLOYEE emp = db.App3_EMPLOYEEs
        .Single(e => e.PKEY == employee.PKEY);
        
    db.App3_EMPLOYEEs.Attach(employee, emp);
    db.SubmitChanges();
    return employee.PKEY;
}

But I don't want to use the second option. Is there any efficient way to update data?

I am getting this error by using both ways:

An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext. This is not supported.

like image 504
Pranay Rana Avatar asked May 20 '10 09:05

Pranay Rana


People also ask

Which is faster LINQ or SQL?

More importantly: when it comes to querying databases, LINQ is in most cases a significantly more productive querying language than SQL. Compared to SQL, LINQ is simpler, tidier, and higher-level.

Is LINQ to SQL obsolete?

"As long as LINQ to SQL lives under Entity Framework, it's dead.

How do you update a record in LINQ?

You can update rows in a database by modifying member values of the objects associated with the LINQ to SQL Table<TEntity> collection and then submitting the changes to the database. LINQ to SQL translates your changes into the appropriate SQL UPDATE commands.


3 Answers

I find following work around to this problem :

1) fetch and update entity (I am going to use this way because it's ok for me )

public int updateEmployee(App3_EMPLOYEE employee)
{
    AppEmployeeDataContext db = new AppEmployeeDataContext();
    App3_EMPLOYEE emp = db.App3_EMPLOYEEs.Single(e => e.PKEY == employee.PKEY);
    emp.FIRSTNAME = employee.FIRSTNAME;//copy property one by one 
    db.SubmitChanges();
    return employee.PKEY;
}

2) disable ObjectTrackingEnabled as following

// but in this case lazy loading is not supported


    public AppEmployeeDataContext() : 
                    base(global::LinqLibrary.Properties.Settings.Default.AppConnect3DBConnectionString, mappingSource)
            {
                this.ObjectTrackingEnabled = false;
                OnCreated();
            }

3) Detach all the related objects

partial class App3_EMPLOYEE
{
    public void Detach()
    {
        this._APP3_EMPLOYEE_EXTs = default(EntityRef<APP3_EMPLOYEE_EXT>);
    }
}

 public int updateEmployee(App3_EMPLOYEE employee)
{
    AppEmployeeDataContext db = new AppEmployeeDataContext();
    employee.Detach();
    db.App3_EMPLOYEEs.Attach(employee,true);
    db.SubmitChanges();
    return employee.PKEY;
}

4) use Time stamp in the column

 http://www.west-wind.com/weblog/posts/135659.aspx

5) Create stored procedure for updating your data and call it by db context

like image 159
Pranay Rana Avatar answered Oct 10 '22 18:10

Pranay Rana


You cannot attach a modified entity to a DataContext when there is no RowVersion column. Instead you could store original entity in your application as long as maintaining a copy for data changes. Then when changes need to be saved you could attach original entity to a DataContext, change its values to match the modified entity values and submit changes.

Here is an example:

public int updateEmployee(App3_EMPLOYEE employee, App3_EMPLOYEE originalEmployee)
{
    DBContextDataContext db = new DBContextDataContext();
    db.App3_EMPLOYEEs.Attach(originalEmployee);

    // TODO: Copy values from employee to original employee

    db.SubmitChanges();
    return employee.PKEY;
}

Update:

There is a table in the database with columns ID, Name, Notes

// fetch an employee which will not be changed in the application
Employee original;
using(var db = new TestDbDataContext())
{
  original = db.Employees.First(e => e.ID == 2);
}

// create an instance to work with
var modified = new Employee {ID = original.ID, Name = original.Name, Notes = original.Notes};

// change some info
modified.Notes = string.Format("new notes as of {0}", DateTime.Now.ToShortTimeString());  
// update
using(var db = new TestDbDataContext())
{
  db.Employees.Attach(original);
  original.Notes = modified.Notes;
  db.SubmitChanges();
}
like image 29
dh. Avatar answered Oct 10 '22 17:10

dh.


There is a discussion on this topic here at MSDN s recommend you to use an IsVersion field and the Attach method

like image 44
Devart Avatar answered Oct 10 '22 19:10

Devart