|
First, don't use the OleDbDataAdapter for SQL Server! Use the SQL Server-specific classes in the System.Data.SqlClient namespace. They exhibit much more functionality and provide features that the generic OLE DB providers can't provide (at least in an abstract manner).
Second, use a typed DataSet , or construct one programmatically at runtime (not fun). You can create an identity column in one of your tables. When you insert a row into that DataTable , the column value is incremented to the next identity using your incremental step. This allows your FK column to reference the identity PK. This is easy to do.
The trick in a multi-user database-driven application is when you use that DataSet to update the database using SqlDataAdapter.Update . You should read the article, Inserting relational data using DataSet and DataAdapter[^]. Basically, your InsertCommand should also include a SELECT statement to make sure the DataSet is updated appropriately. The relationship that would exist in the DataSet for the PK/FK would update the FK with the PK value that was actually used when the row was inserted.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Heath Stewart wrote:First, don't use the OleDbDataAdapter for SQL Server!
We might change the Database engine later from SQL Server 2000 to Oracle 9i, and that's why we tried to use the OleDB Data Provider.
Heath Stewart wrote:
Second, use a typed DataSet, or construct one programmatically at runtime (not fun).
I don't see anything fun in this quote. I've never ever used an untyped DataSet, since it has got many drawbacks...
Heath Stewart wrote:
You should read the article, Inserting relational data using DataSet and DataAdapter[^].
Thanks a lot, I read the article and it will certainly solve my problem after two damn weeks of trying to post the same question here and there.
I do really appreciate your help.
Thank you for your time,
Mehdi Mousavi - Software Architect [ http://mehdi.biz ]
|
|
|
|
|
Mehdi Mousavi wrote:
We might change the Database engine later from SQL Server 2000 to Oracle 9i, and that's why we tried to use the OleDB Data Provider.
Reasonable enough. I just get used to saying this because so many with no such plans use the OLE DB provider and are trying to do SQL Server-specific things many times.
Mehdi Mousavi wrote:
I don't see anything fun in this quote. I've never ever used an untyped DataSet, since it has got many drawbacks...
Constructing typed DataSet classes using the DataSet designer is definitely a heck of a lot easier than trying to code the same thing, plus gives you typed access to columns which is much faster. Sure, the same thing could be done manually, too, but again it can be tedious.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
my computer is stand alon and connected to a busy router( which is been serving its services for different ISPs ) how can i communicate with that router to get knowledge of about its channel connection quality (like parameters latency, pakcet loss etc)
kashif<programming luvr>
|
|
|
|
|
This is specific to the firmware for the router. You need to consult the router manufacturer web site for details, if any are provided.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
use SNMP to communicate with the router.
but I haven't done something like this in c# til now.
|
|
|
|
|
|
Dear forum members,
I have controls (UserControl) designed in C#.
Can anyone tell me how I can embed them in MFC dialogs/views (in VC7) ?
Any sample code will be very helpful.
Thanks in advance.
|
|
|
|
|
|
hi,
do u know how to write and read from serial port. actually i have done the write and read but i do not know how to configure the port.
do anyone know in c#?
bye thank u
|
|
|
|
|
There are several articles on this here on CodeProject and it has been covered before in this forum. Please search the CodeProject site for more information.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
|
Often, in my code, I use the following construct:
string someStr = "sdlkfj" + someOtherStr + "slkdfj";
One of my colleague rather uses the following:
string someStr = String.Format("sdlkfj{0}slkdfj", someOtherStr);
Which one do you think is better, and why?
Thanks
--------
"I say no to drugs, but they don't listen."
- Marilyn Manson
|
|
|
|
|
If your code uses "your way" of doing things often, your colleague's way is better. Performing the operation the way you specified:
string x = "bob" + stringObj + "bob";
actually allocates memory for all three RHS values (iirc), not to mention the fact that string concatenation in itself is not particularly speedy or memory efficient.
However, if you only use it sparingly, or in non-critical sections, your way doesn't really have a problem either. I generally use string concatenation unless performance becomes an issue, in which case I usually switch over to a StringBuilder.
Jeremy Kimball
magnae clunes mihi placent, nec possum de hac re mentiri.
(Large buttocks are pleasing to me, nor am I able to lie concerning this matter)
|
|
|
|
|
Jeremy Kimball wrote:
actually allocates memory for all three RHS values
Actually, it doesn't. The C# compiler compiles simple string concatenation to calls to String.Concat , which only allocates once.
StringBuilder also has interesting issues: see Concatenating with StringBuilders vs strings[^].
Stability. What an interesting concept. -- Chris Maunder
|
|
|
|
|
The strings are still allocated each time:
string s = string.Concat("One", "Two", "Three"); ...still allocates three strings in order to concatenate them.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Not necessarily true: for each, if it's in the intern pool, the interned string will be returned instead of a newly-created object. At least, that's my understanding. (Check the documentation of String.Intern for a starting point.) From this standpoint, if you have commonly-occurring small strings and go assembling them into formatting strings just to use String.Format() , you will incur extra string-creation overhead PLUS the slowness of the method itself!
Regards,
Jeff Varszegi
|
|
|
|
|
The Format version is more costly in performance. However, it is vastly more flexible; you can position the item to be replaced anywhere in the string. You can even place formats in a different order to the order they're passed to Format , or use the same replacement multiple times. This makes it easier to localize displays for different cultures.
Multiple string concatenations with + in the source code are compiled to calls to String.Concat by the C# compiler, and so don't cause any extra overhead in terms of memory usage.
I'd use Format for any strings presented to a user and which therefore might be localized, and + for any internal string operations.
See also Rico Mariani's blog[^] (a performance architect on the .NET Framework team at Microsoft).
Stability. What an interesting concept. -- Chris Maunder
|
|
|
|
|
easier to localize displays for different cultures
Great point. I guess that goes for any output that's configurable, too. -Jeff
|
|
|
|
|
I think that there are two main possible benefits to some approach: simplicity/ease of understanding and maintenance, and performance. On a line-by-line basis, I always lean in favor of performance, so I would advise you to use whatever works fastest. I often perform small benchmarks if I am not sure of which version of a code section would work best; this gives me a good understanding of how code performs, and I constantly add to this knowledge.
I discovered in the past that String.Format() can be pretty slow, and that's what I found this time. Run the code on your setup and see which comes out on top. -Jeff
<br />
string sdlkfj = "sdlkfj";<br />
string someOtherString = "blah";<br />
string formatString = "sdlkfj{0}slkdfj";<br />
string product = null;<br />
<br />
int loopCount = 100000;<br />
long startTime, endTime;<br />
<br />
startTime = DateTime.Now.Ticks * 100;<br />
for(int x = 0; x < loopCount; x++) {<br />
product = sdlkfj + someOtherString + sdlkfj;<br />
product = sdlkfj + someOtherString + sdlkfj;<br />
product = sdlkfj + someOtherString + sdlkfj;<br />
product = sdlkfj + someOtherString + sdlkfj;<br />
product = sdlkfj + someOtherString + sdlkfj;<br />
product = sdlkfj + someOtherString + sdlkfj;<br />
product = sdlkfj + someOtherString + sdlkfj;<br />
product = sdlkfj + someOtherString + sdlkfj;<br />
product = sdlkfj + someOtherString + sdlkfj;<br />
product = sdlkfj + someOtherString + sdlkfj;<br />
}<br />
endTime = DateTime.Now.Ticks * 100;<br />
Console.WriteLine( (((double)(endTime - startTime)) / ((double)(loopCount * 10))) + " nanoseconds" ); <br />
<br />
startTime = DateTime.Now.Ticks * 100;<br />
for(int x = 0; x < loopCount; x++) {<br />
product = String.Format(formatString, someOtherString);<br />
product = String.Format(formatString, someOtherString);<br />
product = String.Format(formatString, someOtherString);<br />
product = String.Format(formatString, someOtherString);<br />
product = String.Format(formatString, someOtherString);<br />
product = String.Format(formatString, someOtherString);<br />
product = String.Format(formatString, someOtherString);<br />
product = String.Format(formatString, someOtherString);<br />
product = String.Format(formatString, someOtherString);<br />
product = String.Format(formatString, someOtherString);<br />
}<br />
endTime = DateTime.Now.Ticks * 100;<br />
Console.WriteLine( (((double)(endTime - startTime)) / ((double)(loopCount * 10))) + " nanoseconds" ); <br />
<br />
|
|
|
|
|
Yes, I will try that for sure.
Thank you.
--------
"I say no to drugs, but they don't listen."
- Marilyn Manson
|
|
|
|
|
|
In this case, it is much better to use a StringBuilder . A String is immutable so anything you do to it allocates a new string and copies the chars. A StringBuilder is mutable so you are changing the same string without re-alloc'ing new strings each time.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Nope. Like you, I often use StringBuilder, especially if I'm constructing a large string in several steps. It's not always faster, though. Try running the code below on your machine-- I came up with these readings:
190.2736 nanoseconds
951.368 nanoseconds
390.5616 nanoseconds
400.576 nanoseconds
Regards,
Jeff Varszegi
<br />
string sdlkfj = "sdlkfj";<br />
string someOtherString = "blah";<br />
string formatString = "sdlkfj{0}slkdfj";<br />
string product = null;<br />
<br />
int loopCount = 100000;<br />
long startTime, endTime;<br />
<br />
<br />
<br />
startTime = DateTime.Now.Ticks * 100;<br />
for(int x = 0; x < loopCount; x++) {<br />
product = sdlkfj + someOtherString + sdlkfj;<br />
product = sdlkfj + someOtherString + sdlkfj;<br />
product = sdlkfj + someOtherString + sdlkfj;<br />
product = sdlkfj + someOtherString + sdlkfj;<br />
product = sdlkfj + someOtherString + sdlkfj;<br />
product = sdlkfj + someOtherString + sdlkfj;<br />
product = sdlkfj + someOtherString + sdlkfj;<br />
product = sdlkfj + someOtherString + sdlkfj;<br />
product = sdlkfj + someOtherString + sdlkfj;<br />
product = sdlkfj + someOtherString + sdlkfj;<br />
}<br />
endTime = DateTime.Now.Ticks * 100;<br />
Console.WriteLine((((double)(endTime - startTime)) / ((double)(loopCount * 10))) + " nanoseconds" ); <br />
<br />
startTime = DateTime.Now.Ticks * 100;<br />
for(int x = 0; x < loopCount; x++) {<br />
product = String.Format(formatString, someOtherString);<br />
product = String.Format(formatString, someOtherString);<br />
product = String.Format(formatString, someOtherString);<br />
product = String.Format(formatString, someOtherString);<br />
product = String.Format(formatString, someOtherString);<br />
product = String.Format(formatString, someOtherString);<br />
product = String.Format(formatString, someOtherString);<br />
product = String.Format(formatString, someOtherString);<br />
product = String.Format(formatString, someOtherString);<br />
product = String.Format(formatString, someOtherString);<br />
}<br />
endTime = DateTime.Now.Ticks * 100;<br />
Console.WriteLine((((double)(endTime - startTime)) / ((double)(loopCount * 10))) + " nanoseconds" ); <br />
<br />
startTime = DateTime.Now.Ticks * 100;<br />
for(int x = 0; x < loopCount; x++) {<br />
product = ((new StringBuilder()).Append(sdlkfj).Append(someOtherString).Append(sdlkfj)).ToString();<br />
product = ((new StringBuilder()).Append(sdlkfj).Append(someOtherString).Append(sdlkfj)).ToString();<br />
product = ((new StringBuilder()).Append(sdlkfj).Append(someOtherString).Append(sdlkfj)).ToString();<br />
product = ((new StringBuilder()).Append(sdlkfj).Append(someOtherString).Append(sdlkfj)).ToString();<br />
product = ((new StringBuilder()).Append(sdlkfj).Append(someOtherString).Append(sdlkfj)).ToString();<br />
product = ((new StringBuilder()).Append(sdlkfj).Append(someOtherString).Append(sdlkfj)).ToString();<br />
product = ((new StringBuilder()).Append(sdlkfj).Append(someOtherString).Append(sdlkfj)).ToString();<br />
product = ((new StringBuilder()).Append(sdlkfj).Append(someOtherString).Append(sdlkfj)).ToString();<br />
product = ((new StringBuilder()).Append(sdlkfj).Append(someOtherString).Append(sdlkfj)).ToString();<br />
product = ((new StringBuilder()).Append(sdlkfj).Append(someOtherString).Append(sdlkfj)).ToString();<br />
}<br />
endTime = DateTime.Now.Ticks * 100;<br />
Console.WriteLine((((double)(endTime - startTime)) / ((double)(loopCount * 10))) + " nanoseconds" ); <br />
<br />
<br />
startTime = DateTime.Now.Ticks * 100;<br />
for(int x = 0; x < loopCount; x++) {<br />
product = ((new StringBuilder(16)).Append(sdlkfj).Append(someOtherString).Append(sdlkfj)).ToString();<br />
product = ((new StringBuilder(16)).Append(sdlkfj).Append(someOtherString).Append(sdlkfj)).ToString();<br />
product = ((new StringBuilder(16)).Append(sdlkfj).Append(someOtherString).Append(sdlkfj)).ToString();<br />
product = ((new StringBuilder(16)).Append(sdlkfj).Append(someOtherString).Append(sdlkfj)).ToString();<br />
product = ((new StringBuilder(16)).Append(sdlkfj).Append(someOtherString).Append(sdlkfj)).ToString();<br />
product = ((new StringBuilder(16)).Append(sdlkfj).Append(someOtherString).Append(sdlkfj)).ToString();<br />
product = ((new StringBuilder(16)).Append(sdlkfj).Append(someOtherString).Append(sdlkfj)).ToString();<br />
product = ((new StringBuilder(16)).Append(sdlkfj).Append(someOtherString).Append(sdlkfj)).ToString();<br />
product = ((new StringBuilder(16)).Append(sdlkfj).Append(someOtherString).Append(sdlkfj)).ToString();<br />
product = ((new StringBuilder(16)).Append(sdlkfj).Append(someOtherString).Append(sdlkfj)).ToString();<br />
}<br />
endTime = DateTime.Now.Ticks * 100;<br />
Console.WriteLine((((double)(endTime - startTime)) / ((double)(loopCount * 10))) + " nanoseconds" ); <br />
|
|
|
|
|
Because you don't reinstantiate the StringBuilder ! You use the same one over:
StringBuilder sb = new StringBuilder();
for (int i=0; i<1000; i++)
{
sb.Append("Some string");
sb.Append(i.ToString());
}
Console.WriteLine(sb.ToString()); Of course it's going to take longer when you keep needlessly reinstanting a StringBuilder .
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|