What? By that I could have:
GetByString(String name)
GetByString(String city)
That does not make much sense.
That is also not what I am suggestion ... at all.
I am stating that you can, if you use both IDENTITY and GUID have two
methods:
GetByID(int id)
GetByGuid(Guid id)
If you want to do some custom pulls on a table, it is best to use the
format:
GetBy{FieldName}(string val)
I could do something else which would be:
void Delete(Guid id);
void Create(Asset asset);
void Update(Asset asset);
This is fairly standard for a repository. But you are typing the
repository explicitly. You can actual move the Create, Update or even
encapsulate both in a Save() method, in a generic repository.
As an example, I did a few experiments with a generic repository. here
are some links to blog entries for LINQ to SQL:
http://bit.ly/NzEGP
http://bit.ly/10MkRX
http://bit.ly/FZEd
http://bit.ly/McWzt
NOTE: The entire generic repository was a bit of R&D work. One of the
requirements was the ability to easily pass the objects to a Java
client, so POCO was preferable. I found that a DataSet and a single LINQ
table per DBML worked best to avoid creating additional objects for my
primary key. EF is becomming a possibility in .NET 4.0, as you can use
POCO (plain old CLR objects), which is not a possibility at the time the
blog entries were written.
These are the basic. Then I could create "Specifications" and do the
following:
Asset GetAsset(Some Specification);
IEnumerable<Asset> GetAssets(Some Specification);
Being specifications something like IDEqualTo(...), NameEqualTo(...)
I read about this somewhere but to be honest I am not sure how to
implement it or if it is even a good idea.
If you adhere to interfaces, the standard repository followed by many
will look something like this;
public interface IRepository
{
Object[] GetAll();
Object GetById();
void Delete(Object o);
void Save(Object o);
}
With LINQ to SQL, in a generic way, I had this:
public interface IRepository<T> where T : class
{
List<T> All();
List<T> FindAll(Func<T, bool> exp);
List<T> Where(Func<T, bool> exp);
T Single(Func<T, bool> exp);
T First(Func<T, bool> exp);
T Last(Func<T, bool> exp);
T Save(T entity);
T Insert(T entity);
void Destroy(T entity);
void Delete(T entity);
void UnDelete(T entity);
void MarkForDeletion(T entity);
T CreateInstance();
/// <summary>Persist the data context.</summary>
void SaveAll();
}
I don't like the idea of having to code multiple interfaces, like so:
public interface IPersonRespository
{
Person() GetAllPersons();
Person GetPersonById(Guid id);
}
public interface IOrderRepository
{
Order() GetAllOrders();
Order GetOrderById(Guid id);
}
With generics, I can reduce this to one IRepository. I can then code the
specific stuff on specific repository interfaces, like:
public interface IPersonRepository
{
Person() GetByLastName(string lastName);
Person() GetByFirstName(string firstName);
}
In my original post, I was focusing on how, if a database is
standardized to either IDENTITY or GUID for primary key, you can
genericize the DAL greatly. Then you do not have to rely on Intellisense
to code something like this:
public void ProcessOrderByPerson(int orderid)
{
Order o = OrderRepository.GetById(orderid);
int personId = o.PersonId;
Person p = PersonRepository.GetById(personId);
}
I would not use the word person here. It would be Employee for the sales
person and Customer for the customer, etc. The idea here is GetById()
has a universal meaning that is consistent.
You ultimately have to decide what works for you, but if you use GetById
or perhaps GetById and GetByGuid, you can use generics and save a lot of
coding. If you are using a code generator, then it is not as necessary.
Hope this makes sense.
--
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA
Twitter: @gbworld
Blog:
http://gregorybeamer.spaces.live.com
*******************************************
| Think outside the box! |
*******************************************