So I have a method that I need to get a collection of Repositories from my Bucket, loop through those repositories and find all the records in the repository that need to be expired and then expire them. I am having a problem figuring out how to execute a Invoke using a Func. Any thoughts? Am I going down the wrong path?
public void DeactivateNonTransversableExpiredRecords()
{
databucket = new AdminBucket(PublishingFactory.AuthoringContext);
IEnumerable<Tuple<dynamic, Type>> nonTransversableList = this.GetNonTransversableRepositories(databucket);
foreach (Tuple<dynamic, Type> repository in nonTransversableList)
{
Type repoType = repository.Item1.GetType(); // RepositoryType
var method = repoType.GetMethod("FindBy"); // Method
var entityType = repository.Item2; // EntityType
// Not working
IQueryable recordsToExpire = method.Invoke(new Func<BaseEntity, bool>((x) => x.IsActive));
foreach (var row in recordsToExpire)
{
((BaseEntity) row).IsActive = false;
repository.Item1.Edit((BaseEntity) row);
}
}
}`
EDIT: Solution... the contribution from @Eduard was invaluable in solving this challenge. I will up vote his contribution however, it was not the actual solution that was implemented.
Through the contributed code I found that returning a IQueryable to a dynamic variable like I was doing caused problems when trying to save records back to the database. If you are going for a Read only set then @Eduard's solution will work elegantly.
I ended up creating a publication specific method in the Model's BaseRepository that calls the .FindBy()
method in the same Repository. This publication specific method returns a IList<T>
to the publication application. This allows the dynamic variable to work properly when enumerating the collection and executing an .Edit()
without having to worry about what Types go to what repository. Using the default .FindBy()
returned a IQueryable<T>
which caused EF5 to puke saying 'a new transaction is not allowed because there are other threads running in the session'.
Here is a working sample
Model's BaseRepository Code
public IList<T> GetItemsToExpire(DateTime date)
{
return this.GetActive(x => x.ExpirationDate <= date).ToList<T>();
}
public virtual IQueryable<T> GetActive(Expression<Func<T, bool>> predicate)
{
return this.GetActive().Where(predicate);
}
public virtual new IQueryable<T> GetActive()
{
return this.FindBy(entity => entity.IsActive)
}
Publication Service Code
public void DeactivateNonTransversableExpiredRecords()
{
databucket = new AdminBucket(PublishingFactory.AuthoringContext);
IEnumerable<dynamic> nonTransversableRepositories = this.GetNonTransversableRepositories(databucket);
foreach (dynamic repository in nonTransversableRepositories)
{
dynamic activeRecordsReadyToExpire = repository.GetItemsToExpire(DateTime.Now.AddDays(-1));
foreach (var record in activeRecordsReadyToExpire)
{
((BaseEntity)record).IsActive = false;
repository.Edit(record, true);
}
}
}