所以我有一个方法,我需要从我的 Bucket 中获取存储库的集合,遍历这些存储库并找到存储库中需要过期的所有记录,然后将它们过期。我在弄清楚如何使用 Func 执行 Invoke 时遇到问题。有什么想法吗?我走错路了吗?
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);
}
}
}`
编辑:解决方案... @Eduard 的贡献对于解决这一挑战非常宝贵。我会投票赞成他的贡献,但是,这不是实施的实际解决方案。
通过贡献的代码,我发现在尝试将记录保存回数据库时,像我所做的那样将 IQueryable 返回给动态变量会导致问题。如果您要使用只读集,那么@Eduard 的解决方案将非常有效。
我最终在模型的 BaseRepository 中创建了一个特定于发布的方法,该.FindBy()
方法调用同一存储库中的方法。此发布特定方法返回IList<T>
发布应用程序。这允许动态变量在枚举集合和执行时正常工作,.Edit()
而不必担心什么类型进入什么存储库。使用默认.FindBy()
返回的 aIQueryable<T>
导致 EF5 吐出“不允许新事务,因为会话中正在运行其他线程”。
这是一个工作示例
模型的 BaseRepository 代码
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)
}
出版服务代码
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);
}
}
}