私は、.NET 4.5、EF5、および GenericRepository.EntityFramework で構築されたプロジェクトに取り組んでいます。特にオーサリングと移動に使用されるデータベース内のレコードに対して何らかのアクションを実行するパブリケーション サービスを作成しようとしています。
最初の問題は、型のキャストが(IBaseRepository<BaseEntity>)
失敗することです。の直接キャストを使用して、最初のリポジトリ (以下のサンプル DataBucket クラスに記載されているもの) でテストすると成功します。
object myRepository = p.GetValue(entity, null);
IBaseRepository<MRClassification> risk = myRepository;
myRepository は「MRClassification」オブジェクト タイプを取るため
IBaseRepository<p.PropertyType.GetInterfaces()[0].GenericTypeArguments[0]>
問題は、各リポジトリが同じ署名ではないことです。各リポジトリがタイプとして受け取るエンティティを返すリストを返すことは可能ですか?
共分散の使用を考えましたが、 BaseRepository に T をパラメーターとして取るメソッドがあります
public virtual new void Add(T entity) { do something; }
パブリケーション アプリ コード
public static void DeactivateNonTransversableExpiredRecords()
{
IEnumerable<Tuple<IBaseRepository<BaseEntity>, Type>> nonTransversableList =
GetNonTransversableRepositories(Databucket);
foreach (var repository in nonTransversableList)
{
////IQueryable recordsToExpire =
////((IBaseRepository<BaseEntity>)repository).FindBy(
//// p => Convert.ToDateTime(p.ExpirationDate).Date <= DateTime.Now.Date && p.IsActive);
IQueryable recordsToExpire = repository.Item1.FindBy(p => p.IsActive);
foreach (var row in recordsToExpire)
{
((BaseEntity)row).IsActive = false;
((IBaseRepository<BaseEntity>)repository).Edit((BaseEntity)row);
}
}
}
private static IEnumerable<Tuple<IBaseRepository<BaseEntity>, Type>> GetNonTransversableRepositories(object entity)
{
PropertyInfo[] properties =
entity.GetType().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance);
List<Tuple<IBaseRepository<BaseEntity>, Type>> list = new List<Tuple<IBaseRepository<BaseEntity>, Type>>();
foreach (PropertyInfo p in properties)
{
if (!typeof(ITransversableRepository).IsAssignableFrom(p.PropertyType))
{
if (OpenGenericIsAssignableFrom(typeof(IBaseRepository<>), p.PropertyType))
{
list.Add(
new Tuple<IBaseRepository<BaseEntity>, Type>(
(IBaseRepository<BaseEntity>)Activator.CreateInstance(p.PropertyType),
p.GetValue(entity, null)));
}
}
}
return list;
}
DataModel ソリューションの POCO エンティティとリポジトリ
--- DataBucket
public class DataBucket : Audit, IDataBucket
{
private IMRClassificationRepository mrClassCodeRepository;
public IMRClassificationRepository MRClassificationRepository
{
get { return this.mrClassCodeRepository ?? (this.mrClassCodeRepository = new MRClassificationRepository(this.dataContext)); }
}
...
}
--- Repository Class Headers
public class MRClassificationRepository : BaseRepository<MRClassification>, IMRClassificationRepository
{
...
}
public interface IMRClassificationRepository : IBaseRepository<MRClassification>
{
...
}
public abstract class BaseRepository<T> : CoreRepository<T>, IBaseRepository<T> where T : BaseEntity, IBaseEntity
{
...
}
public interface IBaseRepository<T> : ICoreRepository<T> where T : BaseEntity
{
...
}
--- Entity Class Headers
public class MRClassification : RiskClassification
{
...
}
public abstract class RiskClassification : Revisionable
{
...
}
public abstract class Revisionable : BaseEntity, IRevisionableEntity
{
...
}
public class BaseEntity : IBaseEntity
{
...
}
public interface IBaseEntity : IEntity<Guid>
{
...
}