- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
EntityCollectionBase at runtime (2.0)
Joined: 26-Jan-2006
Hi team!
Migrating to 2.0 and get the folowing compile error:
Using the generic type 'SD.LLBLGen.Pro.ORMSupportClasses.EntityCollectionBase<TEntity>' requires '1' type arguments
I read up in the help something about EntityCollectionBase having inheritance issues, and I am guessing that is what my problem is now. I am using a generic base class I wrote that uses EntityCollectionBase. Child classes of this base class will dynamically set which EntityCollection EntityCollectionBase really is. Here is the code for my base class:
public class QueryCollectionBase : IQueryCollection
{
private EntityCollectionBase collection;
public EntityCollectionBase Collection
{
get{return this.collection;}
set{this.collection = value;}
}
public QueryCollectionBase()
{
this.selectFilter = new PredicateExpression();
this.maxNumberOfItemsToReturn = 0;
this.sortClauses = new SortExpression();
this.preFetchPath = null;
this.relations = new RelationCollection();
}
/// <summary>
/// A predicate or predicate expression which should be used as filter for the entities to retrieve.
/// </summary>
///
private PredicateExpression selectFilter;
public virtual PredicateExpression SelectFilter
{
set{this.selectFilter = value;}
get{return selectFilter;}
}
/// <summary>
/// The maximum number of items to return with this retrieval query. 0 if no limit
/// </summary>67
private int maxNumberOfItemsToReturn;
public int MaxNumberOfItemsToReturn
{
set{maxNumberOfItemsToReturn = value;}
get{return maxNumberOfItemsToReturn;}
}
/// <summary>
/// The order by specifications for the sorting of the resultset. When not specified, no sorting is applied.
/// </summary>
private SortExpression sortClauses;
public virtual SortExpression SortClauses
{
set{this.sortClauses = value;}
get{return sortClauses;}
}
/// <summary>
/// The prefetch path to use. This is null by default and must be instantiated to the EntityType that is being used
/// </summary>
private IPrefetchPath preFetchPath;
public virtual IPrefetchPath PreFetchPath
{
set{this.preFetchPath = value;}
get{return preFetchPath;}
}
/// <summary>
/// The set of relations to walk to construct the total query.
/// </summary>
private RelationCollection relations;
public virtual RelationCollection Relations
{
set{this.relations = value;}
get{return relations;}
}
/// <summary>
/// The page number to retrieve. 0 if pagination is not in use.
/// </summary>
private int pageNumber;
public virtual int PageNumber
{
set{pageNumber = value;}
get{return pageNumber;}
}
/// <summary>
/// The page size of the page to retrieve. 0 if pagination is not in use.
/// </summary>
private int pageSize;
public virtual int PageSize
{
set{pageSize = value;}
get{return pageSize;}
}
/// <summary>
/// The the current index of the page to calculate each line.
/// </summary>
public virtual int PageIndex
{
get{return (this.pageNumber * this.pageSize) - this.pageSize;}
}
/// <summary>
/// The count as provided by GetDbCount(), and is not the same as Collection.Count. This is readonly.
/// </summary>
private int count;
public virtual int Count
{
get{return count;}
}
public virtual void FillCollection ()
{
this.Collection.GetMulti(this.SelectFilter, this.MaxNumberOfItemsToReturn, this.SortClauses, this.Relations, this.PreFetchPath, this.PageNumber, this.PageSize);
this.count = this.Collection.GetDbCount(this.SelectFilter, this.Relations);
}
}
Then I might write a child class like the following which uses the EnitytCollectionBase to perform a GetMulti:
public class ArticleQueryCollection : QueryCollectionBase
{
ArticleCollection ArticleCollection;
private ArticleQueries articleQuery = ArticleQueries.Undefined;
public ArticleQueries ArticleQuery
{
get{return this.articleQuery;}
set{this.articleQuery = value;}
}
private int topicId = DataProperties.UNDEFINED_INTEGER;
public int TopicId
{
set{this.topicId = value;}
}
private int articleId = DataProperties.UNDEFINED_INTEGER;
public int ArticleId
{
set{this.articleId = value;}
}
private int month = DataProperties.UNDEFINED_INTEGER;
public int Month
{
get{return this.month;}
set{this.month = value;}
}
private int year = DataProperties.UNDEFINED_INTEGER;
public int Year
{
get{return this.year;}
set{this.year = value;}
}
public ArticleQueryCollection()
{
this.ArticleCollection = new ArticleCollection();
_ArticleQueryCollection();
}
private void _ArticleQueryCollection()
{
base.Collection = this.ArticleCollection;
}
public override void FillCollection()
{
QueryFactory();
base.FillCollection();
}
#region Custom Predicates
/// <summary>
/// This factory calls the specific query to be used.
/// </summary>
private void QueryFactory()
{
switch(this.ArticleQuery)
{
case ArticleQueries.RecentArticlesFromAllTopics :
QueryRecentArticlesFromAllTopics();
break;
case ArticleQueries.ArchiveArticlesBySelectedMonthYear :
QueryArchiveArticlesBySelectedMonthYear();
break;
}
}
/// <summary>
/// </summary>
private void QueryRecentArticlesFromAllTopics()
{
PrefetchPath preFetchArticleEntity = new PrefetchPath((int)EntityType.ArticleEntity);
IPrefetchPathElement prefetchTopic = ArticleEntity.PrefetchPathTopic;
preFetchArticleEntity.Add(prefetchTopic);
SortExpression sorter = new SortExpression();
sorter.Add(SortClauseFactory.Create(ArticleFieldIndex.CreateDate, SortOperator.Descending));
base.PreFetchPath = preFetchArticleEntity;
base.MaxNumberOfItemsToReturn = 20;
base.SortClauses = sorter;
}
private void QueryArchiveArticlesBySelectedMonthYear()
{
IExpression monthCall = new DbFunctionCall( "MONTH", new object[]{ArticleFields.CreateDate});
IExpression yearCall = new DbFunctionCall( "YEAR", new object[]{ArticleFields.CreateDate});
PredicateExpression selectFilter = new PredicateExpression();
selectFilter.Add(new FieldCompareValuePredicate(ArticleFields.ArticleTopicId, ComparisonOperator.Equal, this.topicId));
FieldCompareValuePredicate filterMonth = PredicateFactory.CompareValue(ArticleFieldIndex.CreateDate, ComparisonOperator.Equal, this.Month);
FieldCompareValuePredicate filterYear = PredicateFactory.CompareValue(ArticleFieldIndex.CreateDate, ComparisonOperator.Equal, this.Year);
filterMonth.FieldCore.ExpressionToApply = monthCall;
filterYear.FieldCore.ExpressionToApply = yearCall;
selectFilter.AddWithAnd(filterMonth);
selectFilter.AddWithAnd(filterYear);
base.SelectFilter = selectFilter;
}
#endregion
}
public enum ArticleQueries : int
{
Undefined = 0,
RecentArticlesFromAllTopics = 1,
ArchiveArticlesBySelectedMonthYear = 2,
}
If I understand correctly the new EnitytCollectionBase requires a type as in:
EnitytCollectionBase<ArticleEntity>
Is there anyway to set this at runtime, such that the type is dynamically set? If this isn't possible, can someone suggest a better alternative?
Thanks!
Joined: 26-Jan-2006
Might have jumped the gun...
Using the code laid out above I modified it to use generics, but now I am not sure how I would call this.collection.GetMulti(params) since this.collection is null, and I can't seem to set it to a new instance of ArticleCollection through the child class.
Here is the abbreviated base class:
public class QueryCollectionBase<TEntity> : IQueryCollection<TEntity>
{
private EntityCollectionBase<EntityBase> collection;
public EntityCollectionBase<EntityBase> Collection
{
get{return this.collection;}
set{this.collection = value;}
}
...
public virtual void FillCollection ()
{
this.Collection.GetMulti(this.SelectFilter, this.MaxNumberOfItemsToReturn, this.SortClauses, this.Relations, this.PreFetchPath, this.PageNumber, this.PageSize);
this.count = this.Collection.GetDbCount(this.SelectFilter, this.Relations);
}
...
Then here is my abbreviated child class, which defines what type the base class' EntityCollectionBase should be, which I think is great, but then what would I set base.Collection to as currently this.ArticleCollection is not compilable?
public class ArticleQueryCollection : QueryCollectionBase<ArticleEntity>
{
ArticleCollection ArticleCollection;
...
public ArticleQueryCollection()
{
this.ArticleCollection = new ArticleCollection();
_ArticleQueryCollection();
}
private void _ArticleQueryCollection()
{
base.Collection = this.ArticleCollection;
}
...
Thanks!
I guess you code should look like the following:
Base class:
public class QueryCollectionBase<IEntity> : IQueryCollection<IEntity>
{
private EntityCollectionBase<IEntity> collection;
public EntityCollectionBase<IEntity> Collection
{
get{return this.collection;}
set{this.collection = value;}
}
Child class:
public class ArticleQueryCollection : QueryCollectionBase<ArticleEntity>
{
EntityCollectionBase<ArticleEntity> ArticleCollection;
...
public ArticleQueryCollection()
{
this.ArticleCollection = new EntityCollectionBase<ArticleEntity>();
_ArticleQueryCollection();
}
private void _ArticleQueryCollection()
{
base.Collection = this.ArticleCollection;
}
...
Joined: 26-Jan-2006
Thanks for the response Walaa..
I tried to change to the code above, but here are the compile errors I get:
Base Class:
public class ArticleQueryCollection : QueryCollectionBase<ArticleEntity>
{
EntityCollectionBase<ArticleEntity> ArticleCollection;
public ArticleQueryCollection()
{
this.ArticleCollection = new EntityCollectionBase<ArticleEntity>();
_ArticleQueryCollection();
}
private void _ArticleQueryCollection()
{
base.Collection = this.ArticleCollection;
}
Chid Class:
public class QueryCollectionBase<IEntity> : IQueryCollection<IEntity>
{
private EntityCollectionBase<IEntity> collection;
public EntityCollectionBase<IEntity> Collection
{
get
{
return this.collection;
}
set{this.collection = value;}
}
Compile Error:
The type 'IEntity' must be convertible to 'SD.LLBLGen.Pro.ORMSupportClasses.EntityBase' in order to use it as parameter 'TEntity' in the generic type or method 'SD.LLBLGen.Pro.ORMSupportClasses.EntityCollectionBase<TEntity>'
If I change it to the following, then I get another error:
public class QueryCollectionBase<TEntity> : IQueryCollection<TEntity>
{
private EntityCollectionBase<EntityBase> collection;
public EntityCollectionBase<EntityBase> Collection
{
get
{
return this.collection;
}
set{this.collection = value;}
}
Cannot create an instance of the abstract class or interface 'SD.LLBLGen.Pro.ORMSupportClasses.EntityCollectionBase<LightMission.DataEntities.EntityClasses.ArticleEntity>'
Which referes to the Child class:
...
public ArticleQueryCollection()
{
this.ArticleCollection = new EntityCollectionBase<ArticleEntity>();
_ArticleQueryCollection();
}
...
The above error makes sense since EntityCoolectionBase is marked as abstract. Any more ideas?
Thanks!
Joined: 26-Jan-2006
Ya know... I just changed everything to use IEntityCollection instead of EntityCollectionBase. I am not sure why I originally used EntityCollectionBase, perhaps there was a reason. But hopefully it all works now.
Thanks for the help!