0

I am trying to update record with LINQ to SQL but in some case value is same as original value then also Enitty framework create Update query unnecessary.

var objForupdate = context.temp.FirstOrDefault();

if(objForupdate != null)
{       
   objForupdate.Name = "VJ";   // Original Value also "VJ"
}

// Create update query for above.
context.SaveChanges(); 

Updated Hey Steven Wood

Here I have scenario where my DB has 20 fields. Sometime some data is same as original data then also Entity framework create update query for that.

It is simple if data row is not in dirty state then no need to update it. But entity frame work create Update query for that also. Just use profile tool to check what kind of query executed on DB server after SaveChanges() method executed.

Solutions

Use following function to check entity object changed or not. If not then it will change it to EntityState.Unchanged from EntityState.Modified.

public static bool ChangeStateIfNotModified(this EntityObject entity, ObjectContext context)
{

    if (entity.EntityState == EntityState.Modified)        
    {    

        ObjectStateEntry state = ontext.ObjectStateManager.GetObjectStateEntry(entity);
        DbDataRecord orig = state.OriginalValues;
        CurrentValueRecord curr = state.CurrentValues;

        bool changed = false;
        for (int i = 0; i < orig.FieldCount; ++i)
        {    

            object origValue = orig.GetValue(i);
            object curValue = curr.GetValue(i);
            if (!origValue.Equals(curValue) && (!(origValue is byte[]) || !((byte[])origValue).SequenceEqual((byte[])curValue)))
            {
               changed = true;
               break;
            }
          }
        if (!changed)
        {
             state.ChangeState(EntityState.Unchanged);
        }
        return !changed;
    }
    return false;
}
VJ.
  • 31
  • 2
  • Please add more description for the problem! – Bassam Alugili Oct 08 '13 at 13:58
  • Just to be clear, LINQ is only used to query data. You're actually trying to update the entity using Entity Framework. There is no update query. Just modify the object. – Yuck Oct 08 '13 at 14:04

2 Answers2

1

If you're looking to not execute the update if the two values are the same, why not do something like:

if(objForUpdate.Name != orignalValue){
      context.SaveChanges();
}

Make sure you dispose your context where appropriate. For instance, if this is in a MVC controller, I'd dispose your context in the controller's Dispose() method.

Mister Epic
  • 16,295
  • 13
  • 76
  • 147
  • For how many fields you are going to do this if you have 40 fields. – VJ. Oct 08 '13 at 14:04
  • If you have 40 fields, you'd need to build a comparison function using `Reflection`. I can't build that out right now, if you don't get a useful answer, I'll look at this later today. – Mister Epic Oct 08 '13 at 14:06
  • Hey Chris we already fighting with performance and with reflection it will definitely reduce performance. Above solution is not working for bulk updating like update 10000 records with single save. One more you don't think Entity Framework care about this thing? – VJ. Oct 08 '13 at 14:16
  • 2
    Don't use EF for bulk operations. For bulk operations, the case is made for stored procedures. – Mister Epic Oct 08 '13 at 14:22
-1

You should use String.Empty instead of '' and verify that the value is really the same or not while debugging.

EDIT: Are you sure it's exactly the same value?

If I take a look at the generated code for a property, it looks like this:

 [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
    [DataMemberAttribute()]
    public global::System.String id
    {
        get
        {
            return _id;
        }
        set
        {
            if (_id != value)
            {
                OnidChanging(value);
                ReportPropertyChanging("id");
                _id = StructuralObject.SetValidValue(value, false);
                ReportPropertyChanged("id");
                OnidChanged();
            }
        }
    }
    private global::System.String _id;

So the value are being compared. Verify the code generated and set a breakpoint to debug it. If the state is changed, then a query would occur. If it's not entering inside the if condition and the update query still occur, the problem is elsewhere.

Francis
  • 367
  • 1
  • 10
  • How can it solve his problem?!!!!! can you explain that please? – Bassam Alugili Oct 08 '13 at 13:57
  • I do not think Chris have given an answer for the problem the question is not clear!? but check this http://blogs.msdn.com/b/brada/archive/2003/04/22/49997.aspx – Bassam Alugili Oct 08 '13 at 14:04
  • String.Empty is no longer optimized vs "". http://stackoverflow.com/questions/151472/what-is-the-difference-between-string-empty-and-empty-string – Alexandre Rondeau Oct 08 '13 at 14:23
  • @allo_man Thanks, I didn't know that. Still thinking before 2.0. – Francis Oct 08 '13 at 14:35
  • @BassamAlugili My guess is the string are not the same. " " and "" are different, and it's hard to see the difference when you think it's empty. – Francis Oct 08 '13 at 15:00
  • Hey Francis thank you for update. Given code is understandable but how could you generate EDMX because in my EDMX designer i don't have such a things. `if(_id != value)`. If you do it manually then it will be lost when EDMX update from DB. – VJ. Oct 09 '13 at 05:12
  • @VJ. I updated from DB via the designer (EF Database-First). So it's generated code. I'm using VS 2010 Pro. I don't know if that make any difference. – Francis Oct 10 '13 at 20:33
  • Ok, I think you first write model and then update DB. Is it like that? If yes then we follow reverse we design DB first and then generate EDMX. – VJ. Oct 11 '13 at 05:40
  • I created the database first and then created the EDMX based on the database automatically using the designer. – Francis Oct 11 '13 at 16:30