views:

80

answers:

3

I have an object that has a property:

[Column]
public Binary Image { get; set; }

When the object is saved the first time every this is OK, but when it is modified I get an exception on SubmitChanges:

The data types image and varbinary(max) are incompatible in the equal to operator.

What might be the problem here?

+1  A: 

Are you getting the, "" exception? The problem is that linq2sql wants to check to make sure it should modify the column before it actually modifies it. I usually don't care as much and am perfectly happy updating the entire row so I put the UpdateCheck = UpdateCheck.Never named parameter in my ColumnAttributes. I.e.,

[Column(UpdateCheck = UpdateCheck.Never)]

Then, when I want to save the item, I just do this:

Table<TEntity> da = MyDataContext.Context.GetTable<TEntity>();

if (entity.Id > 0)
    da.Attach(entity, true);

else
    da.InsertOnSubmit(entity);

da.Context.SubmitChanges();
D. Patrick
-1 You may not care, but your users are likely to.
Mark Seemann
Why mark? In most cases, they really don't care. In my case, my save method is an extension method so you must have an instance. If you just retrieved the object and then saved it, nobody cares if you put the same values back into the row as were already there. It's also more performant unless you want to add the timestamp field to every entity table.
D. Patrick
Why? A user pulls up some data on a screen, works with that data and saves it. Five minutes later it turns out that the changes he or she made has disappeared, and you say that it doesn't matter? I bet that user would disagree.
Mark Seemann
I'm saying the problem has been solved many times over. If it's easier to deal with concurrency yourself, you can and probably should. You shouldn't be afraid to work outside the box. Keep in mind, this is the same problem that existed before linq2sql when two users loaded the same form at the same time, modified data, and the fastest modifier was disappointed by the results. The answer to the question, "what might be the problem" is "concurrency check" and I recommended a potential solution assuming CoffeeCode is clever enough to consider dealing with concurrency his-/her-self.
D. Patrick
By the way Mark, is your book going to be out in print? I'd like to read it, but it looks like it's currently online only.
D. Patrick
@D. Patrick: It's going to be printed when it's done, but that's going to take a while yet. Until then, what's written is available online.
Mark Seemann
A: 

I think you may be running into the default Optimistic Concurreny behavior in LINQ to SQL (and I believe that LINQ to Entities work the same way).

Unless told otherwise, just before you update a row, it issues a SELECT statement against the previous values of all columns in the row to see if someone else modified them while you kept them in memory.

However, it sounds like it doesn't know how to compare two Binary instances.

If this is the case, you have two options:

  • Use a more explicit version of Optimistic Concurrency by identifying the row version based on a designated timestamp row (preferred)
  • Disable Optimistic Concurrency

Here's the documentation for Optimistic Concurrency for LINQ to SQL.

Mark Seemann
Why the downvote? No reason?
Mark Seemann
A: 

Just step back a second - how are you comparing these variables?

Are you computing a hash for the images? Comparing the hashes is much better than comparing the images byte for byte.

Alex