|
I would suggest a seperate layer for the Data Definition.
passing of Data between the layers is required in almost all the cases. There are two different ways of doing this in .NET. One option you pointed-out.. using Generic Dataset. There is another way of handling this. By using Strongly Typed DataSet. A Typed-Dataset is similar to a Generic Dataset because it is derived from the Dataset class and inherits all the members of a dataset. But the only difference is the Typed dataset is created with the XML Schema representation of the Database Table and the corressponding class file. So it provides type-safe operation and all the methods, properties, events are defined and also it provides an excellent way to access the tables and columns using the names. The only disadvantage of using typed dataset is that it put slightly higher overload on the application.
We can have a seperate layer named DataDefinition and we can have all the database table's in the form of .xsd files which is the XML schema representation of the database tables.
Regards John
|
|
|
|
|
If you are looking at using an object-oriented data layer then you should read this article[^].
|
|
|
|
|
Hi
What do you recomend to populate custom objects from the database?
Let's say i have a "Product" object, and i have a Products table, each product has a "name", "Id","Stock","Type" etc.
Some times i need to get a couple of products while other times i need a large list of them,
So i build a Singleton "Products" class that has a "GetProduct(id)" method and a private Dictionary of products, each time a product is requested it first check if the product is in the dictionary, and if its not it calls a New Product(id) and add it to the dictionary.
Class Products
Public Shared Function GetProduct(id as integer) as product
if Cache.containskey(id) then return Cache(id)
return new product(id)
end function
End class
Then i have a constructor in the "product" Class that looks like this:
Sub New(id as integer)
Dim Comm as new sqlcommand("Select * from products where id=@id",ConnString)
comm.parameters.addwithvalue("@id",id)
Dim Reader as sqldatareader=comm.executereader
reader.read
idvalue=reader("Id")
Namevalue=reader("Name")
end sub
The problem i think is that when i need to get a large number of products i am making a lot of querys to the database, so i thougt of doing somenthing like this:
Class Product
Private Sub PopulateFromReader(r as datareader)
idvalue=reader("Id")
Namevalue=reader("Name")
end sub
Sub New(r as datareader)
me.PopulateFromReader(r)
end sub
Sub New(id as integer)
Dim Comm as new sqlcommand("Select * from products where id=@id",ConnString)
comm.parameters.addwithvalue("@id",id)
Dim Reader as sqldatareader=comm.executereader
me.PopulateFromReader(r)
end sub
End class
And then in the private constructor of the Singleton "Products" class i do somenthing like this:
Class Products
Private Cache as dictionary(of Integer,Product)
Private Sub New
Dim Comm as new sqlcommand("Select * from products",ConnString)
Dim Reader as sqldatareader=comm.executereader
do while reader.read
Cache.add(reader("id"),new product(reader)
loop
end sub
end class
So, what do you think i should do? is it ok? is there a "Correct" way to do it?
Thanks in advance
PS: Sorry my english!
|
|
|
|
|
You could try the free edition of Diamond Binding by following the link in my signature. This will pretty much do what you are after, without you having to write any code.
If you are really insistant on DIY you could tag all your fields with attributes and then write a templated base class that uses reflection to populate the fields. If you only have a few tables, it will probably be easier to not use a data layer at all to be honest.
What you've written will work, but you'll need to remember to keep your cache up to date when you insert/update records.
|
|
|
|
|
Mark Churchill wrote: If you are really insistant on DIY you could tag all your fields with attributes and then write a templated base class that uses reflection to populate the fields. If you only have a few tables, it will probably be easier to not use a data layer at all to be honest.
You might be interested an article here on CP, the Tale of the Three Monkeys or something like that, basically outlining pros and cons of using hand-written DALs, Reflection generated DALs and thirdly (whole point of the article) generated custom code using Reflection.Emit and DynamicMethod s. Just search google with monkey site:codeproject.com and it should be first link.
|
|
|
|
|
Hi
Does anyone know if there is any available (or up coming) seminar about Design Patterns in Europe.(In English language).
Thanks in advance
|
|
|
|
|
I don't know of any, but I can arrange one if you wish.
Upcoming events:
* Glasgow: Mock Objects, SQL Server CLR Integration, Reporting Services, db4o, Dependency Injection with Spring ...
"I wouldn't say boo to a goose. I'm not a coward, I just realise that it would be largely pointless."
My website
|
|
|
|
|
That sounds like a cracking idea.
Deja View - the feeling that you've seen this post before.
|
|
|
|
|
Hi Colin
I am very interested to attend such a seminar. Please send me more info on how could i do that
Thanks in advance
|
|
|
|
|
Colin Angus Mackay wrote: but I can arrange one if you wish
Now that would be cool.
"It was the day before today.... I remember it like it was yesterday."
-Moleman
|
|
|
|
|
|
I've just been briefed to convert a manual entry counter sales 'application' to use a Posiflex CD2860 barcode scanner, in keyboard wedge mode. Documentation is non-existant except for a PDF listing various setup barcodes. The only means of sending data to the device seems to be by scanning one of these special barcodes.
I would like to somehow only enable the scanner on certain fields etc. and suspect the way to do this is to implement a 'proxy' layer that checks all keyboard input, then hopefully configure the scanner to prefix all codes it sends, and ignore these inputs. It's here that I would like some suggestions, not actually programming the scanner.
"Once in Africa I lost the corkscrew and we were forced to live off food and water for weeks." - Ernest Hemingway
My New Blog
|
|
|
|
|
Hi
I developed a website with CSS.It is working fine on IE(IE7).
But when I browse the same thing on Mozilla, some CSS properties like Backgroung image to a Header etc. are not working fine.
So can I switch to CSS between different browsers.
I have not failed. I've just found 10,000 ways that won't work. -Thomas A. Edison
Thank u
Chandu
|
|
|
|
|
You can - it's a hack, but it is possible:
<!-- [if IE 7]><link rel=...><![endif]--> By the way, this is the wrong forum for this question. It should be on the Web Development forum.
Deja View - the feeling that you've seen this post before.
|
|
|
|
|
Say you have an interface:
public interface IWidget
{
int Count
{
get;
set;
}
}
Let's pretend that a lot of classes will implement this interface. As a result, each class will have to implement the Count property. The implementation code in each class will be the same, more or less. So it's tempting to do this:
public abstract Widget : IWidget
{
private int count = 0;
public int Count
{
get
{
return count;
}
set
{
count = value;
}
}
}
Now instead of implementing the IWidget interface directly, classes derive from the abstract Widget base class.
Let's say, however, that derived classes need to know when Count changes; they may need to do some house keeping. We could make Count virtual so that derived classes could do this:
public class MyWidget : Widget
{
public override int Count
{
get
{
return base.Count;
}
set
{
base.Count = value;
}
}
}
I've posted about this in the past. I don't like this approach because it seems to introduces an ambiguity. When overriding a virtual method or property, when should you call the base class version? And should the call be at the beginning or at the end of the virtual method or property?
But I'm not really interested in delving into this issue again, though feel free to comment.
The next step is to factor out the Count property into its own class:
public class Counter
{
private int count = 0;
public event EventHandler CountChanged;
public int Count
{
get
{
return count;
}
set
{
if(count < 0)
{
throw new ArgumentOutOfRange("Count");
}
count = value;
OnCountChanged(EventArgs.Empty);
}
}
}
Instead of Count being a property of the IWidget interface, it becomes an object that is passed to instances of IWidget derived classes. Derived classes hook up to the CountChanged event and do whatever house keeping is necessary when the event is raised.
Counter myCounter = new Counter();
IWidget widget1 = new MyFirstWidget(myCounter);
IWidget widget2 = new MySecondWidget(myCounter);
I need to point out that in the scenario I've described above, instances of classes derived from IWidget will share the same count value and will be treated as a group of objects. So instead of iterating through a group of objects changing the property value on each one, you simply change the value of one object which in turn raises an event to notify its observers.
Instead of:
foreach(IWidget widget in widgets)
{
widget.Count++;
}
You have:
myCounter.Count++;
This post has gotten rather long, but it's been a kind of chronicle of the process I went through. I finally arrived at the point where I factored out properties whose values are shared across several objects into a class of its own. This allows several objects to share the same property. I'm posting this more to get feedback and as a general sanity check.
|
|
|
|
|
Hi Leslie,
I did not completely follow the story here.
Count first was a property, I am not sure what it is intended for.
If it counts the number of IWidgets, I guess you would like to have a private static
count variable, and a public static property; but then interfaces don't allow for
static things. And you would not need a setter, the constructor should be the only
one modifying it.
Now if you attempt to solve the static issue by making an explicit Counter class and object,
that's fine except it de-encapsulates things: you are now responsible for passing
the right counter to each of the Widget constructors.
You could solve that by adding another class I think.
But maybe I misunderstood you and you want something completely different...
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips:
- make Visual display line numbers: Tools/Options/TextEditor/...
- show exceptions with ToString() to see all information
- before you ask a question here, search CodeProject, then Google
|
|
|
|
|
Luc Pattyn wrote: I did not completely follow the story here.
Count first was a property, I am not sure what it is intended for.
Erm, count was a bad example, I guess. It's not intended to mean anything other than demonstrating the example. It could have easily been called foo or whatever.
I ran into this situation with my synth toolkit. I had a collection of synth components that shared the same sample rate. At first, I made sample rate a property in an interface that's implemented by synth component classes. I noticed a lot of code duplication, so I factored sample rate into a property in an abstract base class. Some derived classes need to know when the sample rate changes, so I made it a virtual property. Derived classes then have the option to override the property so that when it's set to a new value, they can react. This lead to the ambiguity I described in my post about when/where/if to call base class members.
Finally, I factored sample rate out into a class of its own. This allowed components to share the same sample rate object. It also allowed me to change the sample rate from a single point. Components sharing the same sample rate object would then be updated automatically.
I was trying to describe all of this in my post by using a generic "Widget" class and "Count" property. I should have been more concrete.
|
|
|
|
|
Hi Leslie,
if you moved out the Counter/SampleRate stuff away from IWidget/ISynth and into a
separate class, basically making it (almost) global, I see no objection.
I first was under the impression you were somehow aggregating interfaces, i.e.
defining an interface in an hierarchical way, with Counter somehow inside it. And
that would open some new doors, if it were possible, but in the end I understood
the Counter/SampleRate stuff is orthogonal to the IWidget/ISynth stuff, you just
took it out completely.
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips:
- make Visual display line numbers: Tools/Options/TextEditor/...
- show exceptions with ToString() to see all information
- before you ask a question here, search CodeProject, then Google
|
|
|
|
|
What you have just described is known as composition, and it is perfectly valid. It is one of the most frequently overlooked areas of aggregation in OOP, and is seriously underused. To my mind, composition is as important as inheritance in OO.
Deja View - the feeling that you've seen this post before.
|
|
|
|
|
It looks like a composition, but I'm my opinion, he's implementing the Observer Design Pattern. I think in his project (as in many others), a property from an object is more than a property -- since it's shared among many members, it could be seen as an object itself.
So, you create and object and delegate to punch when the state changes.
I think many people tend to believe since "it's just an int" or "it's just a string" it's not a object.
|
|
|
|
|
Leslie Sanford wrote: I've posted about this in the past. I don't like this approach because it seems to introduces an ambiguity. When overriding a virtual method or property, when should you call the base class version? And should the call be at the beginning or at the end of the virtual method or property?
But I'm not really interested in delving into this issue again, though feel free to comment.
hehe I know it's not the main issue but since you invited comments ... it's not ambiguous it's flexable. You should know (either because you wrote it or because the documentation tells you) exactly what happens in the base. You then have a choice of wether you want that functionality to happen before your code, after your code or not at all.
|
|
|
|
|
I'm designing a small, off-site backup service for some existing clients. I'm wondering about how to go about managing the transfer and storage of backup sets. One client may have more than one backup file, from more than one source, that they elect to upload to my service daily. Two of the initial design issues are:
1. It seems more workable if I bundle all backup files into a single 'batch' file, using an archive tool.
2. I will probably use FTP and thus need to encrypt backup batches before upload. I would prefer to not decrypt files for storage, but rather only on retrieval, enhancing security. Clients will be provided with the decryption tool to ensure against the even of my service not being available for retrieval.
I would appreciate comment on these two strategies as well as any more general comment. Last modified: 51mins after originally posted --
"Once in Africa I lost the corkscrew and we were forced to live off food and water for weeks." - Ernest Hemingway
My New Blog
|
|
|
|
|
I read that twice and failed to find any question
|
|
|
|
|
I guess that's why it was not marked as a question, but as a "General" message.
If anything it is quite a pre-anouncement.
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips:
- make Visual display line numbers: Tools/Options/TextEditor/AllLanguages/General
- show exceptions with ToString() to see all information
- before you ask a question here, search CodeProject, then Google
|
|
|
|
|
Sorry, it's modified now. I just wanted comments on my two 'question points'. The appropriateness of each of those is a 'question point' to me.
"Once in Africa I lost the corkscrew and we were forced to live off food and water for weeks." - Ernest Hemingway
My New Blog
|
|
|
|