質問

Let' say I have a TestClass in my C# app with property A and property B. I change the value of B by my code, I leave property A unchanged. I update TestClass in database by SimpleRepository's Update method.

As I see it updates also property A value in the database.

It is easy to test: I change value A in my database outside my app ('by hand'), then I make the update from my app. Value of property A changes back to its value according to TestClass's state in my app.

So, my question: is it possible to make updates only to some properties, not for the whole class by SimpleRepository? Are there some 'IgnoreFields' possibilities?

役に立ちましたか?

解決

What you need is optimistic concurrency on your UPDATE statement, not to exclude certain fields. In short what that means is when updating a table, a WHERE clause is appended to your UPDATE statement that ensures the values of the fields in the row are in fact what they were when the last SELECT was run.

So, let's assume in your example I selected some data and the values for A and B were 1 and 2 respectively. Now let's assume I wanted to update B (below statement is just an example):

UPDATE TestClass SET B = '3' WHERE Id = 1;

However, instead of running that statement (because there's no concurrency there), let's run this one:

UPDATE TestClass SET B = '3' WHERE Id = 1 AND A = '1' AND B = '2';

That statement now ensures the record hasn't been changed by anybody.

However, at the moment it doesn't appear that Subsonic's SimpleRepository supports any type of concurrency and so that's going to be a major downfall. If you're looking for a very straight forward repository library, where you can use POCO's, I would recommend Dapper. In fact, Dapper is used by Stackoverflow. It's extremely fast and will easily allow you to build in concurrency into your update statements because you send down parameterized SQL statements, simple.

  1. This Stackoverflow article is an overall article on how to use Dapper for all CRUD ops.
  2. This Stackoverflow article shows how to perform inserts and updates with Dapper.

NOTE: with Dapper you could actually do what you're wanting to as well because you send down basic SQL statements, but I just wouldn't recommend not using concurrency.

他のヒント

Don't call the update method on the DataObject for such cases, you are basically indicating that the object has been changed and needs to be updated in the DB. So subsonic will generate a query like

UPDATE TestClass SET A ='', B='', ModifiedOn = 'DateHere' WHERE PrimaryKey = ID

to change only the property B you need to consturct the UPDATE query manually. have a look at the Subsonic.Update class.
Ideally you shouldn't be forming a new instance of the data object manually, if you do so make sure the values are copied from the object retured from the Subsonic.Select query.
So when you update the value of even only one property all other properties will hold their own value from DB rather than a default value depending on the type of the property.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top