Most efficient way to update with LINQ to SQL

前端 未结 6 1273
臣服心动
臣服心动 2020-12-28 16:50

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?

  pub         


        
相关标签:
6条回答
  • 2020-12-28 17:28

    This is a function in my Repository class which I use to update entities

    protected void Attach(TEntity entity)
    {
       try
        {
           _dataContext.GetTable<TEntity>().Attach(entity);
           _dataContext.Refresh(RefreshMode.KeepCurrentValues, entity);
        }
        catch (DuplicateKeyException ex) //Data context knows about this entity so just update values
        {
           _dataContext.Refresh(RefreshMode.KeepCurrentValues, entity);
        }
    }
    

    Where TEntity is your DB Class and depending on you setup you might just want to do

    _dataContext.Attach(entity);
    
    0 讨论(0)
  • 2020-12-28 17:30

    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();
    }
    
    0 讨论(0)
  • 2020-12-28 17:30

    Use this extend method for update all properties that are column attributes:

    public static void SaveToOriginal<T>(this T original, T actual)
        {
            foreach (var prop in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance)
                .Where(info => info.GetCustomAttribute<System.Data.Linq.Mapping.ColumnAttribute>() != null))
            {
                prop.SetValue(original, prop.GetValue(actual));
            }
        }
    

    I mean, first you recover the original from database, use the method to map all columns attributes from new element to original, and at last do a submit. I hope this helps.

    0 讨论(0)
  • 2020-12-28 17:39

    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

    0 讨论(0)
  • 2020-12-28 17:41

    You can attach a unattached modified entity, by using this overload:

    db.App3_EMPLOYEEs.Attach(employee, true);//Attach as modfieied
    

    Note that for this to work you need in your table a "Version" column of type "timestamp"

    0 讨论(0)
  • 2020-12-28 17:43

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

    0 讨论(0)
提交回复
热议问题