使用反射在通用存储库中升级派生实体

时间:2012-07-02 20:45:35

标签: c# entity-framework reflection repository-pattern derived-class

存储库模式有点新。尝试构建一个通用存储库,该存储库还将处理派生实体的状态更改。到目前为止我所做的是创建一个自定义属性来将属性标记为需要被置顶的属性。

属性:

public class DerivedObjectAttribute : Attribute
{
    public enum EntityType
    {
        REFERENCE,
        OBJECT
    }

    public EntityType DerivedType { get; set; }
}

我为任何想要级联状态更改的属性定义此属性。

示例实体:

public class FightingCharacter : BaseEntity 
{
    public Costume costume { get; set; }

    [DerivedObject(DerivedType=DerivedObjectAttribute.EntityType.REFERENCE)]
    public SpecialFinish specialFinish { get; set; }

    [DerivedObject(DerivedType = DerivedObjectAttribute.EntityType.REFERENCE)]
    public List<MoveList> moveList { get; set; }
}

因此对于这个类,服装属性不需要级联,但是specialFinish和moveList属性应该。

然后在我的存储库中:

public class DataRepository<T> : IRepository<T> where T : BaseEntity {
    private void TryDerivedUpsert(T entity)
    {
        Type type = entity.GetType();
        PropertyInfo[] piList = type.GetProperties();
        foreach (PropertyInfo pi in piList)
        {
            foreach (DerivedObjectAttribute attr in pi.GetCustomAttributes(typeof(DerivedObjectAttribute), false))
            {
                // What to do here?
            }
        }
    }
}

在最里面的循环中,我能够毫无问题地精确定位DerivedObjectAttributes。问题是:如何获取对象的类型和值,然后将其挂起?换句话说:如果将属性pi标记为级联更改,则创建一个repo强制转换为相应的实体,然后将其Upsert。 E.G:

DataRepository<EntityType> repo = new DataRepository<EntityType> ();
repo.Upsert(property as EntityType);

这有意义吗?或者我完全以错误的方式进行通用回购?如果它确实有意义(我会感到惊讶),该怎么做? (此处列出的示例仅仅是示例,BTW。我仍然在构建并且还没有EF类。)

1 个答案:

答案 0 :(得分:0)

您可以使用pi.GetValue(entity, null)获取值,并为属性类型(来自pi)创建通用存储库(Activate.CreateInstance),但您必须进行大量反思。

在这种情况下,您应该考虑删除经典的通用存储库构思(每种类型的单独存储库)并使用可以处理所有类型的扩展DbContext之类的东西。

如果您有断开连接的方案(WCF),主要问题将是EF本身,因为您必须将所有更改复制到服务器端的嵌套列表并手动更改EntityState。