【问题标题】:Pass object from one generic method where T : MyClass to another where T : DerivedClass将对象从 T : MyClass 的一个泛型方法传递到另一个 T : DerivedClass 的方法
【发布时间】:2013-03-28 17:20:36
【问题描述】:

我有一个包含此方法的通用存储库:

public void Delete<T>(T item) where T : EntityBase

我正在尝试向某些对象添加软删除行为; IE。删除时,它们不会从数据库中删除,而是将 bool Deleted 设置为 false 并且它们停止出现在查询中,除非将特定参数设置为包含它们。一般来说,应用程序的行为就好像它们不存在一样,除了管理视图,这些项目可以通过再次翻转该布尔值来恢复。我的问题是,在将对象传递给此方法时,它被处理为EntityBase,它没有这种软删除行为,因为许多类不需要它。 SoftDeleteEntityBase 扩展了 EntityBase 类以添加软删除行为,但我找不到一种干净的方法来转换对象以便我可以得到布尔值。我的第一个想法是:

public void Delete<T>(T item) where T : EntityBase
{
    if (item is SoftDeleteEntityBase)
    {
        ((SoftDeleteEntityBase)item).Deleted = true;
        Update<T>(item);
    }
    else
    {
        db.Set<T>().Remove(item);
    }
}

但这给了我错误"Cannot convert type T to SoftDeleteEntityBase"

我如何得到那个布尔值?

【问题讨论】:

  • (项目为 SoftDeleteEntityBase).Deleted = true;
  • @JohnLiu 可能NullReferenceException
  • 感谢 llya,假设在函数开始时进行检查。不是这个声明。
  • @JohnLiu 实际上......是的,换掉那条线是可行的。我不太清楚我是如何记得我可以在支票中使用is,但忘记了我可以在转换中使用as。如果您想将其发布为答案,我会接受。
  • 没关系,谢谢。我建议您考虑如何处理软删除。看起来您正在将业务逻辑隐藏到基础架构组件中。

标签: c# entity-framework inheritance polymorphism


【解决方案1】:

这个简短的解决方案怎么样,但考虑更改存储库的设计

SoftDeleteEntityBase itemAsSoft = item as SoftDeleteEntityBase;
if (itemAsSoft != null)
{
    itemAsSoft.Deleted = true;
    Update(itemAsSoft);
}

我不知道你的上下文,但是这个带有泛型的解决方案怎么样

void Main()
{
    Delete(new Base()); // called with base
    Delete(new Derived()); //called with derived
}
public void Delete(Base item)
{
    Console.WriteLine ("called with base");
    //one logic
    GenericDelete(item);
}

public void Delete(Derived item)
{
    Console.WriteLine ("called with derived");
    //another logic
    GenericDelete(item);
}

public void GenericDelete<T>(T item)
{}

public class Base
{}

public class Derived : Base
{}

【讨论】:

    【解决方案2】:

    理想情况下,您会利用多态性。 EntityBase 类可以有一个Delete 方法;它和其他实现可以选择进行硬删除。 SoftDeleteEntityBase 类可以覆盖该方法,而是选择仅设置 Deleted 字段而不是硬删除它。那么这里的这个方法就不需要关心派生类型是什么了;它可以只调用Delete 并让班级自己选择。

    【讨论】:

    • 我不完全确定这将如何工作......这个存储库通过实体框架操作我的数据库,所以我必须将整个数据上下文传递到对象的 Delete 方法中,该方法对我来说似乎很乱。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-11
    • 1970-01-01
    • 1970-01-01
    • 2019-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多