Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
XML To Dataset
Message
De
24/03/2008 16:20:55
 
Information générale
Forum:
ASP.NET
Catégorie:
Code, syntaxe and commandes
Titre:
Divers
Thread ID:
01303148
Message ID:
01305108
Vues:
24
That sounds like a good idea!!

~~Bonnie



>What about this?
>
>1) Make a trip to the DB to get a DS using a sproc. The sproc will mark the records in the DS as locked in
>the semaphore table.
>
>2) At the client side, write out the PK's of all the records to a local file/table.
>
>3) When the app is done with the records, delete the records from the semaphore and from the local file.
>
>4) When the app starts, any PK's still in the local file should be unlocked in the semaphore before proceeding.
>
>This way, all the user has to do after a crash is restart the app. There should still be the admin function, but
>this technique would keep the need for that to a minimum.
>
>
>
>
>
>
>
>
>>>I tossed this idea around some before, but I got hung up on what to do if the user's PC crashes. If that happens,
>>>the semaphore is left undeleted and the record is permanently locked. Any thoughts on handling this?

>>
>>That's why I said you need to have functionality in an Admin module to release "locked" records.
>>
>>~~Bonnie
>>
>>
>>
>>>
>>>
>>>
>>>>Kevin,
>>>>
>>>>Another option, which we have kicked around but haven't seriously done any development with (hence, the reason I can't really give you any concrete examples), is to use semaphore locking.
>>>>
>>>>Basically it boils down to having a table that contains info such as table, table's PK, user and lock datetime. When the user retrieves a record from a table, an entry goes into this table. Once the record is updated the entry is deleted. What you do with ths semaphore lock is up to what kinds of stuff your app needs to do. For example, you may wish to allow a user to retrieve a locked record anyway, but notify him of the fact that this record is currently being edited and may be out-of-date and also don't let him save changes. Or you may not allow it to be retrieved at all. You should also have admin functionality that would unlock records for the famous "user went out for a long lunch" scenario.
>>>>
>>>>~~Bonnie
>>>>
>>>>
>>>>
>>>>>I was thinking aloing those lines on the way home last night. I have a 180 mile round trip each so I get plenty
>>>>>of time to think.
>>>>>
>>>>>At any rate, my problem with this is that the user won't know that the back end changed until AFTER they hit Save.
>>>>>
>>>>>What do you do at this point?
>>>>>
>>>>>
>>>>>
>>>>>>Kevin,
>>>>>>If you need basic locking functionality may I suggest having an UpdatedDate field in your database. Set it originally to a default value (1/1/1900 or something of that sort). The value should make a round trip from the database, through all of your data processing, and back to the database. In your Update Stored Proc, update the record if and only if the UpdatedDate on the record matches the @UpdatedDate parameter you pass in. If the update succeeds, make sure you increment the UpdateDate field back to the current date.
>>>>>>
>>>>>>Using this method ensures you are always overwriting the same version of the record you originally retrieved.
>>>>>>
>>>>>>>Excellent.
>>>>>>>
>>>>>>>What can I do to handle locking/user conflicts?
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>>>Now that I have recieved the data as XML in the server side class, can you recommend a technique for
>>>>>>>>>getting the data back into the DB?

>>>>>>>>
>>>>>>>>OK, well, you've already figured out how to get the XML back into the DataSet using the StreamReader with the .ReadXml() method (we include a method that does that in all of our DataSet classes).
>>>>>>>>
>>>>>>>>And somewhere in this thread, someone (I think Mike), suggested a way for updating your database and it's basically the way that we do things. Here's something I have posted here many times, but it's easier to post it again rather than search for a message <g>:
>>>>>>>>
>>>>>>>>There are a few more options when updating the database.
>>>>>>>>
>>>>>>>>First, you can use the Update method of the DataAdapter. In order for this to work, your DataSet must have a PrimaryKey defined.
>>>>>>>>
>>>>>>>>You can do it using the CommandBuilder, which will generate update commands for you (note: if you use a Stored Proc, the CommandBuilder only generates the proper insert/update/delete commands for the first table retreived from the Stored Proc):
>>>>>>>>
>>>>>>>>public void UpdateMyData(DataSet ds)
>>>>>>>>{
>>>>>>>>	// The same applies for the Update. It's not necessary to Open/Close the connection.
>>>>>>>>	SqlDataAdapter da = new SqlDataAdapter("select * from bob", this.oConnection);
>>>>>>>>	SqlCommandBuilder sb = new SqlCommandBuilder(da);
>>>>>>>>
>>>>>>>>	da.Update(ds);
>>>>>>>>}
>>>>>>>>
>>>>>>>>Or you can create the various update commands yourself instead of using the CommandBuilder:
>>>>>>>>
>>>>>>>>public void UpdateMyData(DataSet ds)
>>>>>>>>{
>>>>>>>>
>>>>>>>>	SqlCommand sc = new SqlCommand();
>>>>>>>>	sc.Connection = this.oConnection;
>>>>>>>>	da = new SqlDataAdapter(sc);
>>>>>>>>
>>>>>>>>	da.InsertCommand = new SqlCommand("Insert into bob (xyz, abc) VALUES ( @xyz, @abc )", sc.Connection);
>>>>>>>>	da.InsertCommand.Parameters.Add("@xyz", SqlDbType.Int, 8, "xyz");
>>>>>>>>	da.InsertCommand.Parameters.Add("@abc", SqlDbType.VarChar, 50, "abc");
>>>>>>>>
>>>>>>>>	// do the same for da.DeleteCommand & da.UpdateCommand
>>>>>>>>
>>>>>>>>	da.Update(ds);
>>>>>>>>}
>>>>>>>>
>>>>>>>>Or, you can take total control, not use the da.Update() and do it all yourself (this is basically the same code that gets done behind the scenes by the da.Update() method:
>>>>>>>>
>>>>>>>>public void UpdateMyData(DataSet ds)
>>>>>>>>{
>>>>>>>>	SqlCommand sc = new SqlCommand();
>>>>>>>>	sc.Connection = this.oConnection;
>>>>>>>>	sc.Connection.Open();
>>>>>>>>	foreach (DataRow Row in ds.Tables[0].Rows)
>>>>>>>>	{
>>>>>>>>		switch (Row.RowState)
>>>>>>>>		{
>>>>>>>>			case DataRowState.Added :
>>>>>>>>				sc.CommandText = "Insert into bob (xyz, abc) VALUES ( @xyz, @abc )";
>>>>>>>>				sc.Parameters.Clear();
>>>>>>>>				sc.Parameters.Add("@xyz", Row["xyz"]);
>>>>>>>>				sc.Parameters.Add("@abc", Row["abc"]);
>>>>>>>>				sc.ExecuteNonQuery();
>>>>>>>>				break;
>>>>>>>>				
>>>>>>>>			// Do the same for DataRowState Deleted and Modified
>>>>>>>>			case DataRowState.Deleted :
>>>>>>>>				break;
>>>>>>>>			case DataRowState.Modified :
>>>>>>>>				break;
>>>>>>>>		}
>>>>>>>>	}
>>>>>>>>	sc.Connection.Close();
>>>>>>>>}
>>>>>>>>
>>>>>>>>
>>>>>>>>~~Bonnie
Bonnie Berent DeWitt
NET/C# MVP since 2003

http://geek-goddess-bonnie.blogspot.com
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform