2012-07-11 84 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(); 

如果我可以找到一种方法在一个查询中完成所有这些工作,我一定会编辑并重新发布。