2013-05-21 21 views
1

問題Breeze使用EF和Web API查詢本地緩存

我有6個下拉的視圖。其中每個都由Web API調用填充。我希望 使用breeze在本地運行查詢後,從遠程服務器填充它。

當數據調用是針對服務器時,代碼運行正常。問題是當試圖查詢本地緩存時。我從來沒有得到任何結果返回。我的方法是否有缺陷或者我做錯了什麼?

服務器端

查看模型

​​

的的WebAPI [單一樣本方法]

[HttpGet] 
     // GET api/<controller> 
     public object GetSomeVals() 
     { 

      return _context.getClinician(); 


     } 

存儲庫[單一樣本方法]

public IEnumerable<genericDropDown> getDropDownVal() 
{ 
    return context.somemodel(a=>new{a.id,a.firstname,a.lastname}).ToList(). 
        Select(x => new GenericDropDown 
     { value = x.id, option = x.firstname+ " " + x.lastname});} 

} 

客戶端

Datacontext.js

var _manager = new breeze.EntityManager("EndPoint"); 

//Being called from my view model 

    var getDropDownBindings = function(KO1, KO2) { 

//First add the entity to the local metadatastore then populate the entity 

     $.when(
      addDD('clinicianDropDown', webAPIMethod), 
      getData(KO1, webAPIMethod, null, 'clinicianDropDown'), 

      addDD('docTypeDropDown', webAPIMethod); 
      getData(KO2, webAPIMethod, null, 'docTypeDropDown'), 

     ).then(querySucceeded).fail(queryFailed); 


     function querySucceeded(data) { 
      logger.log('Got drop down vals', "", 'dataContext', true); 
     } 

    }; 


//Add the entity to local store. First param is typename and second is 
resource name (Web API method) 

    var addDD = function(shortName,resName) { 

     _manager.metadataStore.addEntityType({ 
      shortName: shortName, 
      namespace: "Namespace", 
      autoGeneratedKeyType: breeze.AutoGeneratedKeyType.Identity, 
      defaultResourceName:resName, 
      dataProperties: { 
       value: { dataType: DataType.Int32, 
       isNullable: false, isPartOfKey: true }, 
       option: { dataType: DataType.String, isNullable: false } 
      } 
     }); 
     return _manager.metadataStore.registerEntityTypeCtor(shortName, null, null); 

    }; 

//Get the data 

    var getData = function(observableArray, dataEndPoint, parameters, mapto) { 
     if (observableArray != null) 
      observableArray([]); 

    //TO DO: Incorporate logic for server or local call depending on 
// whether this method is accessed for the first time 

     var query = breeze.EntityQuery.from(dataEndPoint); 
     if (mapto != null && mapto != "") 
      query = query.toType(mapto); 

     if (parameters != null) 
      query = query.withParameters(parameters); 

//This approach doesnt work on local querying as Jquery complains 
//there is no 'then' method. Not sure how to implement promises 
//when querying locally 

    /*  return _manager.executeQuery(query).then(querySucceeded).fail(queryFailed); 


     function querySucceeded(data) { 
      if (observableArray != null) 
       observableArray(data.results); 


     } 
*/ 


//The array length from this query is always 0 
var data = _manager.executeQueryLocally(query); 
    observableArray(data.results); 
return; 


    }; 

//Generic error handler 

function queryFailed(error) { 

     logger.log(error.message, null, 'dataContext', true); 
    } 

viewmodel.js

//In Durandal's activate method populate the observable arrays 

dataContext.getDropDownBindings (KO1,KO2); 

Viewmodel.html

<select class="dropdown" data-bind="options: KO1, optionsText: 'option', value: 'value', optionsCaption: 'Clinicians'"></select> 

<select class="dropdown" data-bind="options: KO2 optionsText: 'option', value: 'value', optionsCaption: 'Document Types'"></select> 

回答

0

您只能對由元數據描述的類型執行本地查詢。

沒有更多的信息我不能確定,但​​我的猜測是你的GetSomeVals方法沒有返回'實體',而只是鬆散的數據。換句話說,爲了微風能夠執行本地查詢,從方法返回的對象的類型必須是實體(或包含投影內的實體)。這是因爲Breeze知道如何緩存和查詢實體,但沒有想法如何緩存「任意」查詢結果。

請注意,您可以從服務器返回包含不同類型實體的匿名類型(爲了填充主要是靜態的小數據集),但是單個項目必須是「實體」。在這種情況下,Breeze將拆分anon結果並挑出要包含在EntityManager緩存中的實體。

每向您介紹如何執行與承諾的本地查詢的問題,請FetchStrategy.FromLocalCache使用方法

即此查詢

var results = em.executeQueryLocally(query) 

也可以表示爲:

query = query.using(FetchStrategy.FromLocalCache); 
return em.executeQuery(query).then(data) { 
    var results = data.results; 

} 

本地查詢仍在synchonously執行,而是使其看起來異步。

+0

謝謝Jay的回覆。我可以讓你解釋一下更多。所以當你說查詢必須返回實體時,它必須返回每個屬性的完整實體?例如,假設我有一個擁有10個字段和相關城市和國家實體的用戶實體。爲了讓我的用戶的姓名和地址我的查詢將需要返回用戶和user.city和user.country微風能夠查詢緩存?那麼JSON數據將包含所有用戶字段和所有相關的城市和國家字段? – shai

+0

修改了存儲庫查詢以返回實體..它現在讀取返回context.MainEntity.Includes(「RelatedEntities」)..可以在返回的JSON中看到結果。 datacontext代碼已更改爲使用fetchstrategy,並且query.ToType映射已被刪除。查詢緩存時,本地查詢仍返回0結果。 – shai

+0

好的,繼承人發生了什麼事情..一個電話正在發生addDD註冊短名稱,資源名稱和命名空間。因此,即使在針對微風執行的查詢識別資源名稱並嘗試使用命名空間來查找緩存中的實體並且失敗但不拋出任何錯誤時,也不會調用query.ToType。我刪除了使用元數據存儲註冊新EntityType的函數,現在它已經全部變好了。 – shai