2012-07-11 34 views
4

我正在使用LINQ從Microsoft Dynamics CRM Online檢索帳戶類型實體。我無法過濾特定格式化值的列表。我有正確的價值,但我收到零記錄。 我創造我的連接是這樣的:如何在Dynamics CRM 2011中查詢(使用LINQ)FormattedValues

var connection = new CrmConnection("CRMOnline"); 
connection.ProxyTypesEnabled = true; 
CrmOrganizationServiceContext _context = new CrmOrganizationServiceContext(connection); 

我已經試過:

List<Account> items = _context.CreateQuery<Account>() 
           .Where(c => ((OptionSetValue)c["new_accreditationstatus"]).Equals(7)) 
           .ToList(); 

List<Account> items = _context.CreateQuery<Account>() 
           .Where(c => c.GetFormattedAttributeValue("new_accreditationstatus") == "7" 
           .ToList(); 

List<Account> items = _context.CreateQuery<Account>() 
           .Where(c => c["new_accreditationstatus"] == "7" 
           .ToList(); 

最後就拋出一個System.Format異常。

正常屬性的過濾器,即.Where(c => c.AccountNumber.StartsWith("2010"))工作得很好。

+1

如果您啓用代理類型,爲什麼Account.new_accreditationstatus必須通過字符串鍵值來訪問?它沒有爲它創建一個屬性訪問器嗎? – Daryl 2012-07-11 19:01:04

+0

什麼類型的字段是new_accreditationstatus? – glosrob 2012-07-11 19:01:12

+0

@Daryl它不。它只在屬性集合中可用。我沒有設置數據庫,也沒有通過網絡服務訪問。 – 2012-07-11 19:36:56

回答

4

生成早期綁定的CRM文件(考慮crmsvcutil.exe/Xrm.cs在線)和創建的CrmOrganizationServiceContext前期綁定衍生物(俗稱XrmServiceContext)時,您只能獲得訪問_____Set實體。您可以在早期綁定的文件中看到可用的構造函數。

所以,如果你事先知道(INT)的OptionSetValue的值(7,在這種情況下),你可以使用這個值的Where子句中的一個參數,因爲您在別處說:

.Where(c => c.new_AccreditationStatus.Value == 7) 
+0

供將來參考:該實用程序隨附SDK。該幫助位於[link](http://msdn.microsoft.com/zh-cn/library/gg327844.aspx) – 2012-07-11 21:36:56

1

EDIT(試試這個):

var list = _context.AccountSet.Where(c => 
        c.FormattedValues["new_accreditationstatus"] == "7").ToList(); 
+0

這引發了另一個異常:'System.NotSupportedException' - 無效'where'條件。一個實體成員正在調用一個無效的屬性或方法 – 2012-07-11 16:50:41

+0

你可以在代碼中顯示你的'_context'對象的創建嗎? – EkoostikMartin 2012-07-11 17:04:12

+0

編輯了這個問題。 – 2012-07-11 17:48:03

1

另一個大問題,但不幸的是,我認爲這將代表另一failure/"limitation" of the Linq provider,其中沒有提及任何FormattedValues作爲Where條款所允許的用途之一儘管它作爲Select條款中的條款是允許的。

OptionSetValue S中的實際值存儲在StringMap實體,並順便的話,你可以訪問StringMap通過LINQ的實體。一個例子如下。

// This query gets one permissible value for this entity and field. 
var actualValue = _context.CreateQuery("stringmap") 
    .Where(x => x.GetAttributeValue<string>("attributename") == "new_accreditationstatus") 
    .Where(x => x.GetAttributeValue<int>("value") == "7") 
    .Where(x => x.GetAttributeValue<int>("objecttypecode") == Account.EntityTypeCode) 
    .Select(x => x.GetAttributeValue<string>("value")) 
    .Single(); 

但是,試圖在子查詢和原始查詢的版本上構建此查詢,如下所示,會導致出現異常,也會在下面出現。

var actualValues = _context.CreateQuery("stringmap") 
    .Where(x => x.GetAttributeValue<string>("attributename") == "new_accreditationstatus") 
    .Where(x => x.GetAttributeValue<int>("objecttypecode") == Xrm.Account.EntityTypeCode); 

// This (modified) query uses the StringMap values from the previous query in 
// a subquery, linking to the int (attributevalue) value that 
// new_accreditationstatus represents. 
List<Account> items = _context.CreateQuery<Account>() 
    .Where(c => actualValues 
     .Where(x => x.GetAttributeValue<int>("attributevalue") == c.new_accreditationstatus.Value) 
     .Select(x => x.GetAttributeValue<string>("attributevalue")) 
     .Single() == "7") 
    .ToList(); 

...拋出異常。

權限類型讀取未在實體'StringMap'上定義。

這當然是令人沮喪的,因爲不知何故,LINQ的可以查詢在第一個查詢字符串的地圖。

所以你必須先查詢StringMap實體對應於「7」,然後在查詢引用值按如下方式使用該值AttributeValue

var actualValue = _context.CreateQuery("stringmap") 
    .Where(x => x.GetAttributeValue<string>("attributename") == "new_accreditationstatus") 
    .Where(x => x.GetAttributeValue<int>("value") == "7") 
    .Where(x => x.GetAttributeValue<int>("objecttypecode") == Account.EntityTypeCode) 
    .Select(x => x.GetAttributeValue<string>("attributevalue")) 
    .Single(); 

List<Account> items = _context.CreateQuery<Account>() 
    .Where(c => c.new_accreditationstatus = new OptionSetValue(actualValue) 
    .ToList(); 

如果我可以找到一種方法在一個查詢中完成所有這些工作,我一定會編輯並重新發布。