worldspawn wrote:
What I am trying to do is create a reusable assembly too take some of the repetitive code out of my app. It's mostly been successful
One thing that prompted me to create this thread is trying to create a reusable static method I can call to retrieve collections of entities.
This is what I had to do, which I dont like much because I have to pass type EntityCollection to the method. The reason I have to do this is (based on my rudimentary understanding) I either have a to create an EntityCollection and pass in an instance of the entity factory OR i can create an instance of the generic EntityCollection which somehow works out what entityfactory to use I guess.
public static EntityCollectionBase2<T> FetchCollection<T, E>(DataAccessAdapterBase adapter, int entityType, IRelationPredicateBucket filter, ISortExpression sorter, params IPrefetchPathElement2[] prefetchPaths) where T : EntityBase2 where E : EntityCollectionBase2<T>, new()
{
EntityCollectionBase2<T> collection = new E();//Frans see here - problem line
IPrefetchPath2 prefetchPath = new PrefetchPath2((int)entityType);
foreach (IPrefetchPathElement2 pre in prefetchPaths)
prefetchPath.Add(pre);
if (adapter == null)
using (adapter = AdapterRequired())
{
adapter.FetchEntityCollection(collection, filter, 50, sorter, prefetchPath);
}
else
adapter.FetchEntityCollection(collection, filter, 50, sorter, prefetchPath);
return collection;
}
Ok, but why not do:
public static EntityCollection<T> FetchCollection<T, E>(IDataAccessAdapter adapter, int entityType, IRelationPredicateBucket filter,
ISortExpression sorter, params IPrefetchPathElement2[] prefetchPaths)
where T : EntityBase2, IEntity2
{
EntityCollection<T> collection = new EntityCollection<T>(); // factory is determined for you.
IPrefetchPath2 prefetchPath = new PrefetchPath2((int)entityType);
foreach (IPrefetchPathElement2 pre in prefetchPaths)
prefetchPath.Add(pre);
if (adapter == null)
using (adapter = AdapterRequired())
{
adapter.FetchEntityCollection(collection, filter, 50, sorter, prefetchPath);
}
else
adapter.FetchEntityCollection(collection, filter, 50, sorter, prefetchPath);
return collection;
}
The factory will be determined for you. (since september or so, the way to do it was found after release).
Example of use: (this stuff is generated by my front end templates)
RelationPredicateBucket filter = new RelationPredicateBucket();
IPredicateExpression expression = new PredicateExpression()
.Add(QuoteFields.ClientId == key);
filter.PredicateExpression.Add(expression);
SortExpression sorter = new SortExpression();
sorter.Add(QuoteFields.UpdatedOn | SortOperator.Descending);
return (IList)FetchCollection<QuoteEntity, EntityCollection<QuoteEntity>>(null, EntityType.QuoteEntity, filter, sorter, QuoteEntity.PrefetchPathClient, QuoteEntity.PrefetchPathClo,QuoteEntity.PrefetchPathFinanceAddress, QuoteEntity.PrefetchPathLeadType, QuoteEntity.PrefetchPathPolicyStatus, QuoteEntity.PrefetchPathRiskAddress);
which then will become: (cleaned it up a bit)
RelationPredicateBucket filter = new RelationPredicateBucket(QuoteFields.ClientId == key);
SortExpression sorter = new SortExpression(QuoteFields.UpdatedOn | SortOperator.Descending);
return (IEntityCollection2)FetchCollection<QuoteEntity>(null, EntityType.QuoteEntity, filter, sorter,
QuoteEntity.PrefetchPathClient, QuoteEntity.PrefetchPathClo,QuoteEntity.PrefetchPathFinanceAddress,
QuoteEntity.PrefetchPathLeadType, QuoteEntity.PrefetchPathPolicyStatus, QuoteEntity.PrefetchPathRiskAddress);
This uses IEntityCollection2 instead of IList, as IEntityCollection2 is the interface you should use in code where you don't know the generic type.