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

具有可重写值的ASP.NET MVC实体框架父级子级

  •  0
  • TehOne  · 技术社区  · 17 年前

    好吧,让我解释一下我想做什么。

    我有一个名为websitepage的表,其中包含我站点上的所有页面以及有关它们的一些信息。然后,我为所有客户准备了一张客户桌。然后我还有一个名为customerWebsitePage的表,它存储WebsitePage表中某些列的客户值。

    所以,使用实体框架,我导入了这三个表。我要做的是返回一个强类型的WebSitePage列表,该列表包含来自CustomerWebSitePage的任何值(如果有值的话)。例如,我的一个客户为我的一个网站页面添加了一个CustomerWebSitePageName。在这种情况下,我想返回包含customerWebSitePageName而不是WebSitePage名称的网站页面列表。但其他所有内容的原始网站页面名称,因为它没有被重写。

    更重要的是,对于父/子关系,我的websitepage表有一个自己的外键。所以,我还想同时返回子网站页面。我尝试使用函数导入来获取我想要的内容,但后来当然丢失了子页面。

    我使用实体框架和LINQ尝试了几乎所有的方法来获得我想要的东西。但到目前为止,我所尝试的几乎每件事都以一个例外而告终。这里有几个:

    • EntityCollection已初始化
    • 不能在Linq to Entities查询中构造实体或复杂类型“MyEntityModel.WebsitePage”。

    我有一个想法,我可以解决所有这些问题,那就是将parentpageid复制到我的websitepage表中,但这似乎违反了很多原则,我真的不想添加与此相关的维护难题。

    有人知道如何完成这类事情吗?

    A simple DB diagram. http://images.tehone.com/screenshots/2009-08-17_013009.png

    1 回复  |  直到 17 年前
        1
  •  1
  •   ADB    17 年前

    需要返回的对象是CustomerWebSitePage,而不是WebSitePage。原因是,您返回的任何对象都必须了解客户,因为属性将需要它来确定要使用的字段(customerpage或websitepage)。

    考虑到这一点,您可以有一个函数customerWebSitePage.getAllPagesForCustomer(客户C),该函数将返回页的枚举。但是,要实现所需的功能,必须在CustomerWebSitePage中实现一些读取属性。让我们以名称为例。下面将介绍如何在客户网站页面中实现它:

    public string Name
    {
        get{ if( String.IsNullOrEmpty(CustomerWebsitePageName) ) 
                return WebsitePage.Name;
             return CustomerWebsitePageName; }
    }
    

    对于子页,您可以拥有一个属性:

    public IEnumerable<CustomerWebPage> Children
    {
       get
       {
          return WebsitePage.Children.Select( it => it.Customer.CustomerID == this.CustomerID );       }
    }
    

    请注意,使用此设置,您无法对这些新字段运行ef-linq查询(因为它们只存在于对象本身,而不存在于数据库映射中)。如果您想无缝地加载所有子级,可以使用load()来填充代码,但这会导致性能损失。要确保所有子项都已加载,请尝试以下加载功能:

    IEnumerable<CusomterWebPage> GetAllPagesForCustomer(Customer c)  
    {
        return Context.CustomerWebPageSet.Include("WebsitePage").Where( it => it.Customer.CustomerID == c.CustomerID );
    }