Breeze不会正确扩展TPH实体

时间:2013-05-24 04:48:40

标签: entity-framework-5 odata breeze

Breeze不会正确扩展TPH实体。 如果使用TPH,则在微风中使用expand时,expand仅适用于第一个实体,其他属性将为null。如果我改变实体不使用继承,它工作正常。我还测试了在扩展查询中单独返回每个实体,该查询也运行良好。

//客户端代码

        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);
        };

// Controler Endpoint

[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"}]

1 个答案:

答案 0 :(得分:0)

我不怀疑BreezeJS中有错误。

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

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

查询是这样的:

var em = newEm(); // clean, empty EntityManager
return EntityQuery.from('bankRootTPHs').take(3)
    .expand('AccountType, Status'))
    .using(em).execute().then(success).fail(handleFail);

...
function success(data) {
    var entity = data.results[data.results.length-1]; // get the last one (the 3rd)
    var type = data.query.entityType.shortName;

    if (!entity) {
        ok(false, "a query failed to return a single " + type);

    }
    // more tests
    // I just set a breakpoint and inspected 
    // entity.accountType() and entity.status()
    // Both returned the expected related entities

}

我发现相关的Status和相关的AccountType都可以从实体获得。

所以其他错误。

关于您的示例的问题

首先,我被迫观察到你有很多扩展。我统计了5个相关实体。这可能会影响性能。我知道我们不是在谈论这个问题,但我正在呼唤它。

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

我很确定我们没有测试那种情况......这种情况非常罕见。我甚至不确定是否有效!现在我必须接受你的说法,EF允许这样的结构。

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