我已经为此苦苦挣扎了一个星期。我在数据库中有一个 Person Company 表。但是,还有一个 CompanyPerson 的连接表,它具有一些额外的属性,例如 IsPrimaryPerson。伟大的。如果我将每个东西都单独加载到 Breeze 中,那么工作和所有这些东西。

所以问题是我想创建一个人员列表,但与公司一起扁平化,就像一个左外连接,这样我也将每个人和公司放在一条线上,还包括那些没有公司的人。

C# 中的这个 linq 语句给了我那个列表,我使用 linqPad 让它工作。这是一个左外连接sql equivlant。

  from p in Person
    join cp in CompanyPerson
     on p.Id equals cp.PersonId
     into companyPersonGroups
     from cp in companyPersonGroups.DefaultIfEmpty()
    select new {
        Person = p,
        CompanyPerson = cp,
        Company = cp.Company
        }

伟大的。但是,我不知道的是如何通过 webapi2 将这样的列表返回给 Breezejs。问题一是 linq 返回一个匿名对象。我已经尝试像 ContactPerson 对象一样创建并拥有 Person 和 Company 的属性,但我不知道如何重新开始,因为它不是元数据的一部分。

Controller ,由于各种原因,这不起作用,具体取决于我尝试和执行的操作。从“无法在 LINQ to Entities 查询中构造实体或复杂类型‘SiteTrackerModel.ContactPerson’”到其他问题。把它放在这里,以某种方式向你展示我正在尝试的东西。
    [BreezeQueryable(MaxExpansionDepth = 3)]
    [HttpGet]
    public IQueryable<ContactPerson> PersonsFlattened()
    {
        //return _contextProvider.QueryAll<Person>();

        var contacts = from person in _contextProvider.QueryAll<Person>()
                       join companyPerson in CompanyPersons() on person.Id equals companyPerson.PersonId into companyPersonGroups
                       from companyPerson in companyPersonGroups.DefaultIfEmpty()
                       select new ContactPerson()
                       {
                           FirstName = person.FirstName,
                           IsPrimaryPerson = companyPerson.IsPrimaryPerson,
                           CompanyName = companyPerson.Company.Name
                       };

        return contacts;

    }

BreezeJs 调用 Angular
return EntityQuery.from("PersonsFlattened")
                 //.toType("ContactPerson")
                 .orderBy(orderBy)
                 .using(self.manager).execute()
                 .then(querySucceeded, self._queryFailed);

这是我试图压平并恢复 Breeze 的类(class)/表格。我已经削减了大部分属性

Person.cs(Edmx/db 中的 Person 表)
public partial class Person
{
    public Person()
    {
        this.Companies = new HashSet<CompanyPerson>();
    }

    public int Id { get; set; }
    public string UserName { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public virtual ICollection<CompanyPerson> Companies { get; set; }
}

CompanyPerson.cs(Edmx/db 中的 CompanyPerson 表)
public partial class CompanyPerson
{
    public int PersonId { get; set; }
    public int CompanyId { get; set; }
    public bool IsPrimaryPerson { get; set; }

    public virtual Company Company { get; set; }
    public virtual Person Person { get; set; }
}

Company.cs(edmx/db 中的公司表)
public partial class Company
{
    public Company()
    {
        this.Projects = new HashSet<Project>();
        this.PhoneNumbers = new HashSet<CompanyPhoneNumber>();
        this.Addresses = new HashSet<CompanyAddress>();
        this.Persons = new HashSet<CompanyPerson>();
    }

    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<CompanyPerson> Persons { get; set; }
}

我什至尝试在 sql 中创建一个给我数据的 View ,但我无法让 Breezejs 弄清楚它是什么,但这只是实现上述目标的一种手段。扁平化的人员和公司列表,即使他们没有公司。

最佳答案

您可以将投影数据发送到 BreezeJS 并将它们转换为您在客户端定义的自定义 EntityType。您不能期望 ContactPerson 类型出现在 Entity Framework 生成的服务器的元数据中;它是一个 DTO,而不是 EF 知道的模型的一部分。

这不应阻止您在 Breeze 客户端上定义 ContactPerson。在文档中了解如何 create client-side metadata



下一个技巧是让 BreezeJS 意识到您的投影数据应该在客户端转换为 ContactPerson 实体。

默认情况下,Breeze 不会识别匿名类型数据。您可以为 toType query clause 提供一些帮助。在客户端元数据中定义类型后,您可以在查询中取消注释该子句。

return EntityQuery.from("PersonsFlattened")
       .toType("ContactPerson") // Should work after defining ContactPerson on client
       .orderBy(orderBy)
       .using(self.manager).execute()
       .then(querySucceeded, self._queryFailed);

如果您转换到服务器端 toType 类型并在元数据中连接“PersonsFlattened”端点和自定义客户端 ContactPerson 类型之间的点,则不需要 ContactPerson 子句。我想我会将该端点重命名为“ContactPersons”以保持一致性。

N.B. :我相信您意识到您已经定义了只读类型。 Breeze 不知道这一点,因此如果您对 BreezeJS 中的 ContactPerson 实体进行更改,管理器将尝试保存它。您的保存尝试将在服务器上抛出,除非您捕获传入的更改并用它做一些奇妙的事情,也许是在 BeforeSaveEntity 方法中。

关于c# - 如何通过 webapi2 将扁平列表返回给 Breeze js?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24441138/

10-13 07:06