2014-05-12 2 views
1

Я пытаюсь получить данные с моего контроллера Webapi2 Breeze с Entity Framework 6 и .NET 4.5.1. И получите ошибку «не удалось найти свойство», когда я использую предложение Where в свойстве навигации. Звонок даже не сделан в контроллер Webapi2Breeze: Не удалось найти свойство: XYZ по типу: YYY при выполнении executeQuery в менеджере объектов

Если я не укажу предложение where, данные вернутся правильно.

Соответствующая часть C# класса:

public class NotificationRule { 
    public Guid NotificationRuleId { get; set; } 
    public virtual NotificationRuleSet NotificationRuleSet { get; set; } 
} 

Соответствующая часть С # класса в навигационном NotificationRuleSet собственности:

public class NotificationRuleSet{ 
    public Guid NotificationRuleSetId { get; set; } 
    public virtual List<NotificationRule> NotificationRules { get; set; } 
} 

Соответствующая часть контроллера C# Breeze:

public IQueryable<NotificationRuleSet> NotificationRuleSets() 
    { 
     return _contextProvider.Context.NotificationRuleSets; 
    } 

    public IQueryable<NotificationRule> NotificationRules() 
    { 
     return _contextProvider.Context.NotificationRules; 
    } 

Соответствующая часть запроса (машинописный вид):

  var query = breeze.EntityQuery.from("NotificationRules") 
       .where ("NotificationRuleSet.NotificationRuleSetId","==", this.NotificationRuleSetId) 
       .expand("NotificationRuleSet"); 


      var Result = this.BreezeEntityManager 
       .executeQuery(query) 
       .then((data) => this.RefreshViewModelCallback(data)) 
       .fail((data) => alert("Fail to retrieve data")); 

Если я оставляю где положение вне, данные корректно переданы, как вы можете видеть в этом Скрипач свалка:

{ 
    "$id": "1", 
    "$type": "Imp.Classes.NotificationRule, Imp", 
    "NotificationRuleId": "11111111-be1e-423c-ac5b-f2c689093aca", 
    "NotificationRuleSet": { 
     "$id": "2", 
     "$type": "Imp.Classes.NotificationRuleSet, Imp", 
     "NotificationRuleSetId": "11111111-1bd6-4520-9f69-381504b8e2b2", 
     "NotificationRules": [ 
      { 
       "$ref": "1" 
      } 
     ], 
    }, 
} 

Так что я получаю сообщение об ошибке, что свойство не существует, но похоже, существует.

Использование функции «Где» на невигационном объекте работает нормально.

Я кое-что прочитал о camelCasing, но вместо NotificationRuleSet с уведомлениемRuleSet дает ту же ошибку.

EDIT: Решения, кажется, что NotificationRules в запросе Viewmodels должен начинаться с строчного символа, независимо от того, первый символ имени метода контроллера имеет верхний или нижний регистр.

ответ

2

camelCasing, скорее всего, ваш вопрос при условии, как сущность и свойства существуют -

.where('notificationRuleSet.notificationRuleSetId', "==", this.NotificationRuleSetId) 

Помните, что когда вы camelCasing ваших имен свойств это для свойства навигации, а также.

+0

Я пробовал свой вариант, но тот же результат. Но так как вы были так уверены, что это был camelCasing, я пробовал несколько комбинаций верхнего/нижнего регистра. Кажется, что ТОЛЬКО var query = breeze.EntityQuery.from ("notificationRules") должен быть строчным. Спасибо, что вернули меня на правильный путь. – RHAD

0

Я подумал, что у меня есть объяснение после рассмотрения вашего взаимодействия с PW Kad.

Мое предположение было то, что ACTUAL defaultResourceName для вашего NotificationRule типа - "notificationRules".

Можете ли вы сказать мне, что это такое? Следующее выражение покажет его следующее:

manager.metadataStore.getEntityType('NotificationRule').defaultResourceName; 

Другой вопрос. Вы говорите, что это не удается. Каково исключение сбоя (проверьте полезную нагрузку ответа). Это что-то вроде этого?

$id: "1", 
$type: "System.Web.Http.HttpError, System.Web.Http", 
Message: "The query specified in the URI is not valid.", 
ExceptionMessage: "A binary operator with incompatible types was detected. Found operand types 'Edm.Guid' and 'Edm.String' for operator kind 'Equal'.", 
ExceptionType: "Microsoft.Data.OData.ODataException", 

Вот что я думал. В большинстве случаев Бриз не должен знать корневой тип запроса, когда этот запрос отправляется на сервер. Он может просто дождаться результатов запроса и причины по JSON, чтобы определить тип (или типы).

Но случайный запрос включает сравнение фильтров, которое неоднозначно в его типе данных. GUID - хороший пример. Если бриз не знает тип корня запроса, он не может точно знать, что «11111111-be1e-423c-ac5b-f2c689093aca» в «foo ==» 11111111-be1e-423c-ac5b-f2c689093aca »должен быть строкой или GUID. Человек предположил бы, что это GUID; Бриз не так уверен. Вы можете быть уверены, что только если вы знаете тип данных свойства «foo».

Breeze будет составлять запрос в любом случае. Если он угадывает строку, если создает URL-адрес, который выглядит как «... foo eq» 11111111-be1e-423c-ac5b-f2c689093aca «...», и это не сработает (для меня в любом случае).

Я думал, что это может быть вашей проблемой.

Я пробовал эксперимент в DocCode, который, как я думал, продемонстрировал бы его. Я изменил имя конечной точки для запроса заказа на то, что НЕ является Order типа defaultResourceName (что является «Заказом»).

Как это бывает, веб-API не волнует, говорит ли URL «заказы» или «Заказы», ​​поэтому я могу достичь своей цели путать Breeze о корневом типе, указав запрос на «заказы», ​​и запрос должен по-прежнему маршрутизируется веб-API для правильного метода GET контроллера.

Я ожидал, что Бриз будет составлять запрос GUID в виде строки, и поэтому я мог бы дублировать вашу проблему. Вот моя попытка

/********************************************************* 
* Orders of Customers with Alfred's ID 
* Customer is the related parent of Order 
* CustomerID is a GUID 
* Demonstrates "nested query", filtering on a related entity 
* where the filter criteria is ambiguous (string or GUID) 
* and only knowing the root query type (Order) can disambiguate. 
* The 'defaultResourceName' for Order is "Orders", not "orders" 
* so I expect this test to fail ... but it doesn't ... 
* because Breeze disambiguated anyway. 
*********************************************************/ 
test("orders of Customers w/ Alfred's ID (resource name is lowercased)", 2, function() { 

    var query = EntityQuery.from("orders") 
     .where("Customer.CustomerID", "==", testFns.wellKnownData.alfredsID) 
     .expand("Customer"); 

    verifyQuery(newEm, query, "orders query", showOrdersToAlfred); 
}); 

К сожалению, тест проходит!

Это URL, который Breeze отправляется на сервер:

http://localhost:56337/breeze/Northwind/orders?$filter=Customer.CustomerID eq guid'785efa04-cbf2-4dd7-a7de-083ee17b6ad2'&$expand=Customer 

DAMN Breeze (v.1.4.12) был слишком умен для меня. Как-то выяснилось, что мое сравнительное значение - GUID ... несмотря на то, что не знает корневой тип запроса.

Это означает, что у меня нет объяснения причин, почему в вашем примере breeze.EntityQuery.from("notificationRules") работает, но breeze.EntityQuery.from("NotificationRules") нет.


Может быть, у меня будет еще одна идея, как только вы говорите нам defaultResourceName и показать нам URL-адреса, которые генерируются (а), когда он работает, и (б), когда он не работает.

+0

Я попытался воспроизвести мою проблему. Восстановил мои решения из Visual Studio Online. Я не могу точно воспроизвести проблему. Я думаю, что я (к сожалению) не проанализировал свою проблему правильно. Также была проблема с этим. NotificationRuleSetId, который должен был быть notificationRuleSetID. Я пробовал все шаги по реорганизации, и я думаю, что решение проблемы заключается в том, что NotificationRules должен начинаться с нижнего регистра n, независимо от первого символьного случая имени метода breezecontroller. - – RHAD