1

Breeze 无法正确扩展 TPH 实体。如果您使用 TPH 扩展,则在微风中使用时,扩展仅适用于第一个实体,其他属性将为空。如果我将实体更改为不使用继承,它可以正常工作。我还测试了在扩展查询中分别返回每个实体,该查询也可以正常工作。

//客户端代码

        var getResidentById = function (id, obs) {

            var query = EntityQuery.from('Residents')
                .where('id', '==', id)
                .expand('user, currentUnit, leases, leases.unit, leases.leaseStatus');

            return manager.executeQuery(query).then(function (data) {
                if (obs) {
                    obs(data.results[0])
                }
            }, queryFailed);
        };

//控制器端点

[HttpGet]
public IQueryable<Resident> 
{
   return _context.Context.UserDetails.OfType<Resident>();
}

//模型

public class UserDetail : EntityBase<int>, IArchivable, IHasPhoto, IDeactivatableEntity, IUpdatable
    {
        public bool IsArchived { get; set; }
        public int LastUpdatedById { get; set; }
        public UserProfile LastUpdatedBy { get; set; }
        public DateTimeOffset LastUpdatedDate { get; set; }
        public string PhotoUri { get; set; }
        public bool IsInactive { get; set; }
    }

    public abstract class UserBelongsToApartmentComplex : UserDetail, IBelongsToApartmentComplex
    {

        public int ApartmentComplexId { get; set; }
        public virtual ApartmentComplex ApartmentComplex { get; set; }

        public virtual bool IsInSameComplexAs(IRelatedToApartmentComplex otherEntity)
        {
            return ApartmentComplexId == otherEntity.ApartmentComplexId;
        }
    }

    public class Staff : UserBelongsToApartmentComplex
    {
        public string Title { get; set; }
    }

    public class Admin : UserDetail
    {
        public string AccessLevel { get; set; }
    }

    public class Resident : UserBelongsToApartmentComplex
    {
        public string Pets { get; set; }
        public bool HasInsurance { get; set; }
        public virtual IList<Lease> Leases { get; set; }
        public int? CurrentUnitId { get; set; }
        public virtual Unit CurrentUnit { get; set; }

        public Resident()
        {
            Leases = new List<Lease>();
        }
    }

//从端点响应来自服务器的数据 public IQueryable Residents()

[{"$id":"1","$type":"RadiusBlue.Core.Models.Resident, RadiusBlue.Core","Pets":"Sadie, a westie","HasInsurance":false,"Leases":[{"$id":"2","$type":"RadiusBlue.Core.Models.Lease, RadiusBlue.Core","Start":"2012-05-23T00:00:00.000","End":"2013-05-23T00:00:00.000","UnitId":2,"Unit":{"$id":"3","$type":"RadiusBlue.Core.Models.Unit, RadiusBlue.Core","Building":"B","Floor":2,"ModelName":"Tera","RentAmount":2500.00,"NumberOfBeds":1,"NumberOfBaths":3,"UnitName":"102A","IsInactive":true,"Inhabitants":[],"ApartmentComplexId":1,"ApartmentComplex":{"$id":"4","$type":"RadiusBlue.Core.Models.ApartmentComplex, RadiusBlue.Core","Name":"The Stratford","StreetAddress":"100 S Park Ave","City":"Winter Park","StateId":10,"ZipCode":"32792","PropertyManagementCompanyId":1,"IsInactive":false,"TimeZoneId":"Eastern Standard Time","TimeZone":{"$id":"5","$type":"System.TimeZoneInfo, mscorlib","Id":"Eastern Standard Time","DisplayName":"(UTC-05:00) Eastern Time (US & Canada)","StandardName":"Eastern Standard Time","DaylightName":"Eastern Daylight Time","BaseUtcOffset":"-PT5H","AdjustmentRules":[{"$id":"6","$type":"System.TimeZoneInfo+AdjustmentRule, mscorlib","DateStart":"0001-01-01T00:00:00.000","DateEnd":"2006-12-31T00:00:00.000","DaylightDelta":"PT1H","DaylightTransitionStart":{"$id":"7","$type":"System.TimeZoneInfo+TransitionTime, mscorlib","TimeOfDay":"0001-01-01T02:00:00.000","Month":4,"Week":1,"Day":1,"DayOfWeek":"Sunday","IsFixedDateRule":false},"DaylightTransitionEnd":{"$id":"8","$type":"System.TimeZoneInfo+TransitionTime, mscorlib","TimeOfDay":"0001-01-01T02:00:00.000","Month":10,"Week":5,"Day":1,"DayOfWeek":"Sunday","IsFixedDateRule":false}},{"$id":"9","$type":"System.TimeZoneInfo+AdjustmentRule, mscorlib","DateStart":"2007-01-01T00:00:00.000","DateEnd":"9999-12-31T00:00:00.000","DaylightDelta":"PT1H","DaylightTransitionStart":{"$id":"10","$type":"System.TimeZoneInfo+TransitionTime, mscorlib","TimeOfDay":"0001-01-01T02:00:00.000","Month":3,"Week":2,"Day":1,"DayOfWeek":"Sunday","IsFixedDateRule":false},"DaylightTransitionEnd":{"$id":"11","$type":"System.TimeZoneInfo+TransitionTime, mscorlib","TimeOfDay":"0001-01-01T02:00:00.000","Month":11,"Week":1,"Day":1,"DayOfWeek":"Sunday","IsFixedDateRule":false}}],"SupportsDaylightSavingTime":true},"Users":[{"$ref":"1"}],"Groups":[],"IsArchived":false,"ApartmentComplexId":1,"Id":1},"Id":2},"ResidentId":3,"Resident":{"$ref":"1"},"LeaseStatusId":4,"LeaseStatus":{"$id":"12","$type":"RadiusBlue.Core.Models.LeaseStatus, RadiusBlue.Core","Description":"Lost","Id":4},"Id":1},{"$id":"13","$type":"RadiusBlue.Core.Models.Lease, RadiusBlue.Core","Start":"2013-05-24T00:00:00.000","End":"2014-05-24T00:00:00.000","UnitId":1,"Unit":{"$id":"14","$type":"RadiusBlue.Core.Models.Unit, RadiusBlue.Core","Building":"A","Floor":2,"ModelName":"Aqua","RentAmount":2000.00,"NumberOfBeds":2,"NumberOfBaths":1,"UnitName":"101A","IsInactive":true,"Inhabitants":[{"$ref":"1"}],"ApartmentComplexId":1,"ApartmentComplex":{"$ref":"4"},"Id":1},"ResidentId":3,"Resident":{"$ref":"1"},"LeaseStatusId":1,"LeaseStatus":{"$id":"15","$type":"RadiusBlue.Core.Models.LeaseStatus, RadiusBlue.Core","Description":"Active","Id":1},"Id":2}],"CurrentUnitId":1,"CurrentUnit":{"$ref":"14"},"ApartmentComplexId":1,"ApartmentComplex":{"$ref":"4"},"Id":3,"User":{"$id":"16","$type":"RadiusBlue.Core.Models.UserProfile, RadiusBlue.Core","UserName":"vjiawon@gmail.com","FirstName":"Vishal","LastName":"Jiawon","Age":27,"PhoneNumber":"123 456 7890","IsInactive":false,"UserDetail":{"$ref":"1"},"GroupMembers":[],"MaintenanceRequests":[],"Id":3},"IsArchived":false,"LastUpdatedById":1,"LastUpdatedDate":"0001-01-01T00:00:00.000+00:00","IsInactive":false,"CreatedById":1,"CreatedDate":"0001-01-01T00:00:00.000+00:00"}]
4

1 回答 1

0

我不怀疑 BreezeJS 的某个地方存在错误。

我可以报告说,至少从 v.1.3.4 开始,Breeze 可以扩展 TPH 类的多个导航属性……而不仅仅是在返回的第一个实体上

我刚刚在 DocCode 中的继承Tests.js 中修改了“可以导航到 AccountType 急切加载扩展”测试,以便 (a) 它还扩展了导航,并且 (b) 测试在返回的第三个实体而不是第一个实体上执行。Status

查询是这样的:

var em = newEm(); // 干净的,空的 EntityManager
return EntityQuery.from('bankRootTPHs').take(3)
    .expand('AccountType, 状态'))
    .using(em).execute().then(success).fail(handleFail);

...
功能成功(数据){
    var entity = data.results[data.results.length-1]; // 获取最后一个(第三个)
    var type = data.query.entityType.shortName;

    如果(!实体){
        ok(false, "查询返回单个" + 类型失败);

    }
    // 更多测试
    // 我只是设置了一个断点并检查了
    // entity.accountType() 和 entity.status()
    // 两者都返回了预期的相关实体

}

我看到相关AccountType和相关Status都可以从实体获得。

所以还有其他问题。

关于您的示例的问题

首先,我不得不观察到你有很多扩展。我数了 5 个相关实体。这可能会损害性能。我知道我们不是在谈论这个,但我要大声疾呼。

其次,超类UserDetail是具体的,而中间派生类UserBelongsToApartmentComplex是抽象的。你有继承类层次结构,具体/抽象/具体。查询的类型Residents就是这样一个类。每个级别的类都映射到“UserDetail”表,是吗?

我很确定我们没有针对这种情况进行测试……这很不常见。我什至不确定这是否有效!现在我必须相信你的话,EF 允许这样的构造。

BreezeJS 似乎对此感到困惑。我们来看看。

于 2013-05-24T21:19:43.947 回答