如何在Breezejs中查询和扩展多态导航集合属性

时间:2014-04-02 19:14:29

标签: javascript entity-framework inheritance odata breeze

我们在真实世界的应用程序中第一次使用Breeze,这是一个非常棒的框架。我们遇到了继承问题,因为在查询具有多态导航集合的实体时,我们可以在JSON中看到派生类型返回的数据,但随后集合未填充在客户端上的Breeze实体中。我们在服务器上有C#类,Entity Framework使用Table-Per-Type策略持久保存到数据库。有一个名为Client的基本抽象类,而SpecialClient继承自它:

    public abstract class Client
    {
        public int Id { get; set; }
        public int QuoteID { get; set; } //Foreign Key for navigation

        public string FirstName { get; set; }
        public string FamilyName { get; set; }
    }

    public class SpecialClient : Client
    {
        public decimal Income { get; set; }
        public string ClientType { get; set; }
    }

然后我们有一个名为Quote的父类,它具有基本Client的集合导航属性:

public class Quote
{
    public Quote()
    {
        Clients = new List<Client>();
    }

    public int Id { get; set; }
    public string Reference { get; set; }           
    public string Comments { get; set; }
    public DateTime EffectiveDate { get; set; }

    public List<Client> Clients { get; set; }
}

(我们已将主要/外键属性移动到部分类,但为了简洁起见,将它们显示在相同的类中,不确定部分是否会导致问题?)

然后,我们尝试了一个客户端Breeze查询来检索Quote并展开Clients属性(我们有一个Web API Breeze Controller,使用包含EF上下文和Breeze ContextProvider的存储库进行正常的Quotes Action):

    [HttpGet]
    public IQueryable<Quote> Quotes()
    {
        return _repository.Quotes();
    }

和Breeze查询:

var query = breeze.EntityQuery.from('Quotes').expand('Clients');

查看返回的实体时,我们有一个Quote实体,但Clients数组尚未填充任何客户端实体。我们已经检查了元数据,它看起来很好,它知道基类型和派生类型,我们检查了我们在Quote和Client之间映射的外键,这也反映在元数据中。我们还检查了查询产生的JSON,并且一切看起来都不错,客户端导航集合填充在Quote实体上。当查询返回数据时,Breeze似乎不会填充实体。

我们尝试删除从Client继承的SpecialClient类,然后我们得到了一个填充了基本客户端实体的集合,因此它似乎与继承相关联。我们还试图查看是否可以查询派生的SpecialClient,但我们似乎无法解决如何在导航属性中查询派生类型,该属性使用谓词指定基类型:

var pred = new breeze.Predicate("Clients", "any", "clientType", "==", 'Life1'));

我们不确定如何指定我们想要查询SpecialClient派生类型。当我们尝试上述操作时,Breeze会抱怨Client没有clientType属性。

非常感谢,如果有人可以建议如何处理这种类型的继承查询和扩展问题,我们哪里出错或者这是一个错误(不扩展的部分)。我们正在使用Web API 2(5.0.1),Breeze(使用EF6上下文提供程序)1.4.11,我们检查了所有客户端和服务器软件包都是1.4.11。

我们如何指导Breeze我们在Navigation集合中派生了类型,并且我们想要查询和检索它们?

非常感谢您的帮助!

编辑1:还应该提到我们没有使用除基本约定之外的任何特殊EF映射。

2 个答案:

答案 0 :(得分:2)

通过查看DocCode示例,我们似乎已经解决了这个问题。事实证明,我们没有从基类Client返回到包含基本客户端导航集合的主要类Quote的引用导航:

public abstract class Client
{
    public int Id { get; set; }
    public int QuoteId { get; set; } //Foreign Key for navigation

    public string FirstName { get; set; }
    public string FamilyName { get; set; }

    public Quote quote { get; set; }    //Added this nav property back to Quote principle!
}

虽然我们对原则的外键有一个QuoteId属性,但看起来我们还需要一个从基本Client类引用的引用。我们现在可以使用expand进行查询,并且Clients集合中填充了派生类型。这是在Breeze中实现此类建模的正确方法吗?此外,是否可以在Breeze网站上添加一个关于继承的文档,或者这对于特定的后端ORM选择是否过于具体?

在相关说明中,是否可以对派生类型的属性执行查询限制(wheres或谓词)?我们通过将查询推送到我们的服务器存储库并执行LINQ Where with OfType()获取我们想要限制的属性来解决这个问题,我们想知道Breeze是否可以在客户端执行此操作(我们无法看到文档中有任何明确的内容。)

感谢您的帮助,并与Breeze保持精彩的工作,我们热爱框架!

答案 1 :(得分:0)

我还没详细看过这个,但是在我们的DocCode示例中,我们在Customers和Orders / InternationalOrders之间有类似的关系,其中Customer.Orders属性可以返回Orders或InternationalOrders。看看那个样本,看看它与你的不同。