Duplicate LINQ to SQL entity / record?

前端 未结 5 866
傲寒
傲寒 2021-01-02 02:35

What would be considered the best practice in duplicating [cloning] a LINQ to SQL entity resulting in a new record in the database?

The context is that I wish to mak

相关标签:
5条回答
  • 2021-01-02 02:41

    In Entity framework 6 you can do this

    Dim WorkoutNew As New Workout 'create a record
    ff7db.Workouts.Add(WorkoutNew) 'add it to the table (workout)
    ff7db.Entry(WorkoutNew).CurrentValues.SetValues(WorkoutsPost) ' update its values with a class with the same properties
    
    0 讨论(0)
  • 2021-01-02 02:52

    If you load entity from DataContext with set ObjectTrackingEnabled to false then you can insert this entity as new in another DataContext

    DataContext db1 = new DataContext();
    DataContext db2 = new DataContext();
    
    db2.ObjectTrackingEnabled = false;
    
    MyEntity entToClone = db2.Single(e => e.Id == id);
    
    // ... change some data if it is needed
    
    db1.MyEntities.InsertOnSubmit(entToClone);
    db1.SubmitChanges();
    
    0 讨论(0)
  • 2021-01-02 02:58

    I was stuck with the same problem and Kristofer's code worked perfectly, many thanks!

    In case someone is interested, I slightly modified his code so that instead of accepting the target entity as a parameter, it creates a new object and returns it. Also I have made the sourceEntity parameter to be generic:

     public static T CloneEntity<T>(this DataContext dc, T sourceEntity) where T:class, new()
     {
         var targetEntity = new T();
         //... original method code...
         return targetEntity;
     }
    

    Then I can do the following:

    dataContext.MyEntities.Attach(dataContext.CloneEntity(theEntity));
    
    0 讨论(0)
  • 2021-01-02 02:59

    Create a new instance and then use the linq mapping classes together with reflection to copy member values.

    E.g.

    public static void CopyDataMembers(this DataContext dc,
                                       object sourceEntity,
                                       object targetEntity)
    {
        //get entity members
        IEnumerable<MetaDataMember> dataMembers = 
             from mem in dc.Mapping.GetTable(sourceEntity.GetType())
                                     .RowType.DataMembers
             where mem.IsAssociation == false
             select mem;
    
        //go through the list of members and compare values
        foreach (MetaDataMember mem in dataMembers)
        {
           object originalValue = mem.StorageAccessor.GetBoxedValue(targetEntity);
           object newValue = mem.StorageAccessor.GetBoxedValue(sourceEntity);
    
            //check if the value has changed
            if (newValue == null && originalValue != null 
                || newValue != null && !newValue.Equals(originalValue))
            {
                //use reflection to update the target
                System.Reflection.PropertyInfo propInfo = 
                    targetEntity.GetType().GetProperty(mem.Name);
    
                propInfo.SetValue(targetEntity, 
                                  propInfo.GetValue(sourceEntity, null), 
                                  null);
    
                // setboxedvalue bypasses change tracking - otherwise 
                // mem.StorageAccessor.SetBoxedValue(ref targetEntity, newValue);
                // could be used instead of reflection
            }
        }
    }
    

    ...or you can clone it using the DataContractSerializer:

    internal static T CloneEntity<T>(T originalEntity) where T : someentitybaseclass
    {
        Type entityType = typeof(T);
    
        DataContractSerializer ser =
            new DataContractSerializer(entityType);
    
        using (MemoryStream ms = new MemoryStream())
        {
            ser.WriteObject(ms, originalEntity);
            ms.Position = 0;
            return (T)ser.ReadObject(ms);
        }
    }
    
    0 讨论(0)
  • 2021-01-02 02:59

    Here is he same solution as Peter K., for the Linq-to-Sql Entiry Clone in VB.Net.

        Dim DC As New DataContext
        Dim DCI As New DataContext
        DC.ObjectTrackingEnabled = False
    
            Dim RGF As sf_RuleGroup = (From G In DC.sf_RuleGroups _
                                      Where G.RuleGroupID = CInt(e.CommandArgument) _
                                      Select G).First()
            DCI.sf_RuleGroups.InsertOnSubmit(RGF)
            DCI.SubmitChanges()
    
    0 讨论(0)
提交回复
热议问题