代码之家  ›  专栏  ›  技术社区  ›  mare

具有实体框架和存储库模式的按层次结构实现的表

  •  2
  • mare  · 技术社区  · 14 年前

    我已经用一个抽象文档实体和多个派生实体(blog,page,…)实现了每个层次结构实体的表数据模型。我有使用文档实体的方法签名的存储库接口,如下所示

    public Document Load(Guid firmId, int prettyId)
    {
        // the OfType<> can be OfType<Page>, OfType<Blog>, ...
        var instance = (from c in _ctx.Documents.OfType<X>() where c.firm_id == firmId && c.PrettyId == prettyId select c).FirstOrDefault();
        ...
    }
    

    我只有一个实现存储库的类,它使用document作为从方法返回的类型。对于从文档派生的不同类型,我不需要自定义实现,因为加载、插入和更新的实现细节对所有人都是相同的。我只需要确定/提供我们想要使用的方法的类型。

    希望你能理解我的意思。关于如何建模TPH,请不要参考回复,因为我已经这样做了,而且它的模型很好。

    2 回复  |  直到 14 年前
        1
  •  1
  •   mare    14 年前

    实际上,我发现我不需要运行时检测,因为我可以在编译时在MVC控制器中提供类型,与存储库(只有一个)不同的是,它是特定于类型的(我有pagecontroller、blogcontroller等),如下所示:

    public virtual ActionResult Print(int prettyId)
    {
        //Document invoice = _repository.Load(prettyId, _docType);
        Document invoice = _repository.Load<Invoice>(prettyId);
        ...
    }
    

    在我的存储库界面中,我现在有了:

    // also, please comment, which one is better, this one?
    T Load<T>(int prettyId) where T : Document;
    T Load<T>(Guid firmId, int prettyId) where T : Document;
    
    // or this one?
    //T Load<T1>(int prettyId) where T1 : Document;
    //T Load<T1>(Guid firmId, int prettyId) where T1 : Document;
    

    在知识库实现中,我有:

    public T Load<T>(int prettyId) where T : Document
    {
        return Load<T>(AppState.FirmId, prettyId);
    }
    
    public T Load<T>(Guid firmId, int prettyId) where T : Document
    {
        var instance =
            (from c in _ctx.Documents.OfType<T>()
             where c.firm_id == firmId && c.PrettyId == prettyId
             select c).FirstOrDefault();
        instance.FirmReference.Load();
        instance.ClientReference.Load();
        instance.DocumentItems.Load();
        instance.TaxStatementReference.Load();
        return instance;
    }
    

    这个效果不错,看起来也不错。

        2
  •  0
  •   Community CDub    7 年前

    简单的方法是为要加载的每个特殊文档类型创建单独的方法,或者在加载方法中使用带有一些鉴别器的switch/case语句作为参数。我知道你想避免这样的解决办法。在这种情况下,您应该尝试使用反射,因为不可能在运行时提供泛型类型参数。检查这个 answer 用于调用带反射的泛型方法。您将使用oftype调用基本查询,并获取iqueryalbe的实例,该实例将用于查询的第二部分,其中包含where条件。