|
Okay, I think this is going to sound like a crazy question and I think I already know the answer, but I thought I'd throw it out there just to see if I've missed something.
I have a DAO/DAL (Data Access Object/Data Access Layer) class that communicates with SQL Server. The methods have a number of parameters which map to the parameters being sent into the stored procedure. Because I use a cradle-to-grave naming convention the name of the SQL Parameters are exactly the same as the parameters passed into the method.
Is there any way to iterate over the values being passed into the method and create the appropriate SqlParameter objects? I want to do something like this:
SqlCommand cmd = new SqlCommand("myStoredProcedure");
foreach(ParameterInfo paramInfo in methodParameters)
{
string name = paramInfo.Name;
object value = somethingIDontKnowWhat[name].Value;
cmd.Parameters.Add("@"+name, value);
}
I did think of passing in a Hashtable and iterating over that, but I want the security of the compiler throwing out errors if there are parameters missing.
Any other ideas?
My: Blog | Photos
"Man who stand on hill with mouth open will wait long time for roast duck to drop in." -- Confucious
|
|
|
|
|
The basic idea of layering an application is that the data storage should be totally isolated from the user interface. Your code should not be relying on the fact that the method parameters should have the same names as the parameters in the database. If you change the data storage you might have to change the parameter names, then you have to change the names in the entire application. This is exactly what layering the application is meant to prevent.
So, either layer the application propely, or not at all.
---
b { font-weight: normal; }
|
|
|
|
|
Guffa wrote:
The basic idea of layering an application is that the data storage should be totally isolated from the user interface.
Who mentioned anything about the user interface?
Guffa wrote:
Your code should not be relying on the fact that the method parameters should have the same names as the parameters in the database.
This goes against the ethos of Crade-to-grave naming conventions. This is actually a very constructive part of design. To call something a "name" in one part of the code and a "title" in another part and an "id" in yet another leads to confusion and increases maintenance costs. The design should be precise enough that there is no ambiguity over what something is. If I have to spend 10 minutes tracing through code every time I want to know what some variable actually represents then this is a loss on my time and increases my costs and reduces my productivity.
Guffa wrote:
If you change the data storage you might have to change the parameter names, then you have to change the names in the entire application
I use stored procedures to buffer any changes in the underlying data source. I also have a well designed DAO/DAL to ensure that changes in the return is buffered properly also. I have no worries about changes to the underlying database causing a negative impact on the code above it.
Guffa wrote:
This is exactly what layering the application is meant to prevent.
Layering an application is meant to decouple the various parts of an application. My application is very well decoupled. My DAL/DAO class knows nothing about the business layer and it will never need to. The business layer knows nothing about the backend database and it will never need to. The DAO/DAL classes are the interface into the Data Layer - some people consider them part of the Data Layer as they operate at the boundary between the data and the business layer. The design of my application means that, since my code only ever interacts with the abstract base class, the concrete class can speak to SQL Server, Access, Oracle, MySql or whatever - the factory class decides which needs to be instantiated.
Guffa wrote:
So, either layer the application propely, or not at all.
As I've explained, it is properly layered. Crade-to-grave naming does not mean that coupling increases, it is just a technique to improve the quality of code and reduce maintenance time and costs.
I hope this helps explain my architecture and that I am quite well aware of how to design applications properly. I won't say that it is perfect as I've never found a perfect example of a design as there are always trade offs due to some limitation or another. But I will say that it is a design that I would expect to hold up against many future cycles of development as it moves and changes due to changing business requirements.
My: Blog | Photos
"Man who stand on hill with mouth open will wait long time for roast duck to drop in." -- Confucious
|
|
|
|
|
So your application is so decoupled that you decided it needed to be more coupled?
Well, the information you could get from the method parameters is just not enough to create the parameters. For an example, a string doesn't have a specified maximum length, but a varchar field in the database does.
---
b { font-weight: normal; }
|
|
|
|
|
I was just looking for a way to transfer the parameters passed into the method to parameters to the Stored Procedure. The method is just a proxy to the stored procedure, everything is passed straight through with no real processing. This is not coupling the layers together. It is using the surrogate pattern (see Design Patterns: Elements of Reusable Object Oriented Software by Gamma et al.)
For example at the moment I might have a method in my DAO assembly that looks like this:
public bool InsertData(int id, string name, int someValue)
{
SqlParameter[] spParams = new SqlParameter[3];
spParams[0] = new SqlParameter("@id", id);
spParams[1] = new SqlParameter("@name", name);
spParams[2] = new SqlParameter("@someValue", someValue);
int result = (int)SqlHelper.ExecuteScalar(ConnectionString,
CommandType.StoredProcedure, "InsertData", spParams);
return result==1;
}
As you can see all that is happening is that there is a stored procedure with exactly the same signature (only in SQL) and my DAO class is acting as a proxy or surrogate for the Stored Procedure so that I can layer my application properly and don't have lots of SQL calls dispersed randomly throughout my code.
All I wanted was to see if there was some automated mechanism to transfer the parameter values passed into the method to Stored Procedure without having to manually build up a SqlParameter array.
Now, obviously, if there isn't such a mechanism then that's fine - I just have a bit more work to do for each Stored Procedure.
Guffa wrote:
Well, the information you could get from the method parameters is just not enough to create the parameters
As you can see from my example above, all I need is the name of the parameter and its value. You don't NEED to put in other information.
Guffa wrote:
a string doesn't have a specified maximum length, but a varchar field in the database does.
That isn't of concern the business rules prevent bad data getting through. The Stored Procedures also do their own sanity checks. The EXECUTE permissions on the Stored Procedures will only allow certain users to access them. Users cannot access the tables directly and must go through stored procedures.
As you can see I have thought a lot about the design of the application to ensure that it is properly decoupled and that bad data gets stopped as early as possible, but there additional checks in place to catch anything bad that might get through. I am also constantly refactoring the application to improve the ability to maintain it and improve security.
Are you happy yet that I am actually a competent developer and that I just wanted my original question answered rather than enter into a discussion about my abilities to design an application properly?
My: Blog | Photos
"Man who stand on hill with mouth open will wait long time for roast duck to drop in." -- Confucious
|
|
|
|
|
Colin Angus Mackay wrote:
As you can see from my example above, all I need is the name of the parameter and its value. You don't NEED to put in other information.
No, you don't need to. But then the provider has to do an extra round trip (or several?) to the database to query for the data type to use for each parameter.
Colin Angus Mackay wrote:
Are you happy yet that I am actually a competent developer and that I just wanted my original question answered rather than enter into a discussion about my abilities to design an application properly?
I have never questioned your ability to design an application, I have only pointed out where the method seems to break the entire basis of application layering. I didn't mean to offend you, the answer was only based on you initial question, and what people usually try to do when asking things like that.
---
b { font-weight: normal; }
|
|
|
|
|
How can I broadcast a User Defined Windows Message on C#?. Somthing like BroadcastSystemMessage. I need cath it on DefWndProc on a form.
|
|
|
|
|
It's not a good way to do interprocess communication, but the API function you're looking for is SendMessage[^], or one of it's variants as you see fit.
RageInTheMachine9532
"...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome
|
|
|
|
|
So, I've changed the font(style and characteristics), and the fore and background colors for both selected and not selected on the ColumnHeadersDefaultCellStyle of my DataGridView(Image part A). This is the ONLY place I have modified the information. In the editor itself, only the font changes show up(Image Part B), and when the program is run, neither the font nor the color changes show up(Image Part C). Any ideas if this is a bug with the new DataGridView class or I'm just not setting anything correctly?
Link To Image Goodness of my Problem[^]
|
|
|
|
|
Im currently serializing a objects of type Task, which is defined as
[Serializable]
public class Task
{
public event NameChangedHandler NameChanged;
... etc ...
}
the problem is that there are types which are not Serializable connected to the NameChanged event.
one of these objects are of type class UITask. this causes the serialization process of Task objects to try to serialize the UITask objects contained by
the event which naturally results in a serialization exception.
Does anyone know how to avoid this? I guess it can be done by implementing ISerializable, but there should be an easier solution?
Thanks!
Johan
|
|
|
|
|
I'm not clear on what the desired effect is, here:
1. You want the event serialized, but want some way of bypassing or simplifying the UITask type? - or -
2. You just want to skip serializing the event altogether?
In case 1, there's really no shortcut - either implement ISerializable and deal with it in GetObjectData and a deserialization constructor, or come up with a way to mark UITask as serializable.
In case 2, you can mark the event with a [Field:NonSerialized] attribute, or mark the delegate with a [NonSerialized] attribute.
Of the two choices, I would vote for not serializing the event. When you serialize an event, you're making a request to serialize the entire event subscriber graph, and since it's not usually completely knowable what types may be subscribing to your event (or whether they're serializable), it's a risky move as well as a potentially slow one.
Here's a link to a discussion on the topic:
http://weblogs.asp.net/rosherove/archive/2004/12/29/343659.aspx[^]
Hope this helps.
The most exciting phrase to hear in science, the one that heralds the most discoveries, is not 'Eureka!' ('I found it!') but 'That's funny...’
|
|
|
|
|
Is there a way to edit the msi database with c#. I want to write a program that will change just one registry entry within the msi database and then email the msi to the client.
This will save me the hassle of recompiling the msi and then emailing it to the client.
Thanks in advance.
|
|
|
|
|
Highly doubtful, an MSI is compressed.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
This is not an easy task. You have to get to know the finest of details of how an MSI database works and how all the tables relate to each other. You can start by reading this[^] and following all the links.
Or you can just get Wise for Windows Installer, or some other product that can edit MSI files directly.
RageInTheMachine9532
"...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome
|
|
|
|
|
Asad Hussain wrote:
Is there a way to edit the msi database with c#. I want to write a program that will change just one registry entry within the msi database and then email the msi to the client.
If you download the platform SDK[^], you get a tool called "Orca" which you can use to edit the MSI database. If you know what you want to change (in general, changes to the Registry table are very straigtforward), it's very easy to effect and save the change.
If you are determined to do the changes programatically, this article[^] provides the interop signatures and sample code you'll need.
Once you've opened the database, you just use SQL to UPDATE the tables you want.
Share and enjoy.
Sean
|
|
|
|
|
I am using an iterator, which iterates through the xml file and reads each node.
Can I access an element directly if it has an unique name?
|
|
|
|
|
Yes you can if you know the XPath to it one example of doing this could be something like -
<code>
XmlDocument doc = new XmlDocument();
doc.LoadXml("<root><element1/><element2/></root>");
/*DocumentElement is always the root element of the xml and the parameter supplied in the selectSingleNode method is the XPath*/
XmlNode node = doc.documentElement.selectSingleNode("//element2");
</code>
|
|
|
|
|
I got a listview that is in details mode, and I want to have a changeable line that is a property of listviewitem. Or something like that...
It don't have to be a listview, it only needs to do what I described above...
Niklas Ulvinge aka IDK
|
|
|
|
|
hi there,
i just wondered if it is possible to "host" a .NET WebService withing a WinForms Application ( and not as ASP.NET stuff in IIS).
I know this is no Problem in Java and i´d like to know if i can do this with C#.
we´re developing a business software and we want our WebService in our Application (encapsuled in a Plugin). well...is this just possible?
i tried to just let my class inherit from System.Web.Services.WebService but i have no idea how to access this "WebService" Object.
any ideas? thanks
jkersch
|
|
|
|
|
You have to host ASP.NET in your Windows Forms application because this provides the services that a .NET Web Service uses. In fact, Visual Studio 2005 no longer requires that IIS be installed to develop Web Forms and .NET Web Services because it has a separate process that hosts ASP.NET. See the System.Web.Hosting namespace[^] for details.
Once you've hosted ASP.NET you can do just about everything you'd do when hosted from IIS. Keep in mind that IIS does provide some services, such as setting up and tearing down hosts for ASP.NET, handling hung hosts, etc. You could, of course, make your host do that but you'll need to implement it.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Customer Product-lifecycle Experience
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
I am getting an unexpected OutOfMemoryException when I try to dynamically allocate a large 2 dimensional array. This array requires upto 1 gig of memory. I have 4 gig installed on this XP Pro machine.
My C# code is listed below:
//-------------------------------------------------
NumToBurst = 100;
NumberOfPixels = 2048 * 2048;
try
{
BigImageBuf = null; // de-ref mem from prev alloc
GC.Collect (); // free up mem from prev alloc
BigImageBuf = new byte[NumToBurst, NumberOfPixels * 2 ];
}
catch
{....
//------------------------------------------------
During execution the NumToBurst variable varies from 10-120. The OutOfMemoryException is generated when the NumToBurst value is greater than 92.
No problems with smaller values.
Help!
|
|
|
|
|
With the code you've submitted, there is no problem. I was able to reproduce this on a 1GB machine with a 2.5GB swap file and get it to work to NumToBurst = 169, which works out to be 1.4GB. The entire array went straight to the swap file when it was created. I'm not even calling GC.Collect, which is unncessary in your case, based on what I've seen so far. I think your problem is because of a 2GB limit for any one process. You might want to see this[^] for a bit more information.
RageInTheMachine9532
"...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome
|
|
|
|
|
Is it possible to create a property which shows a small button (like font picker) and when the button is clicked a new form is loaded ?
|
|
|
|
|
Piovra_ wrote:
Is it possible to create a property which shows a small button (like font picker) and when the button is clicked a new form is loaded ?
Yes[^]
Share and enjoy.
Sean
|
|
|
|
|
Hey everyone.
I'm really hoping someone can help me with my problem.
I have an mdicontainer application form. The child forms are opened by double clicking on nodes in a tree control. The default way for a child form to open is not maximized...so when I open one form (not maximized) and then open a second child form (also not maximized), things work fine. However, if I open the first child form and maximize it, then open the second child form (which automatically tries to open maximized), I get an OutOfMemoryException that tells me it can't create the window handle. I stuck a breakpoint in the Load event of the child form and it is never reached. The exception is thrown as soon as it reaches the Show() method of the child form. Please Any ideas? This is driving me crazy.
|
|
|
|