Mathieu Mathieu - 23 days ago 6
C# Question

LinqToCRM does not cast properly

I want to change all my queries from QueryExpression to Linq. In development time, all seems to be just fine, but I always get a cast exception at runtime (can't cast Microsoft.xrm.sdk.entity to Xrm.SystemUser -> Xrm is the early bound classes generated with CrmSvcUtil).

var context = new OrganizationServiceContext(crmService);
SystemUser x = (from c in context.CreateQuery<SystemUser>()
where c.DomainName == @"pfgc\" + Environment.UserName
select c).FirstOrDefault();


This code is straightforward. I've even tried without the Where clause and it won't change anything.

I tried the following (no FirstOrDefault and var instead of SystemUser)

var x = (from c in context.CreateQuery<SystemUser>()
where c.DomainName == @"pfgc\" + Environment.UserName
select c);


This won't throw an exception but x type is Microsoft.xrm.sdk.linq.Query. What am I doing wrong? It seems to be exactly what the SDK suggests to do.

EDIT:

GCATNM has the right answer. In case someone faces the same issue, here's a sample of the working code:

public SystemUser GetCurrentUser()
{
var context = GetOrgContext();
return (from c in context.CreateQuery<SystemUser>()
where c.DomainName == @"pfgc\" + Environment.UserName
select c).FirstOrDefault();
}

public OrganizationServiceContext GetOrgContext()
{
var serviceProxy1 = new OrganizationServiceProxy(organizationUri, homeRealmUri, credentials, null);
serviceProxy1.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior());
return new OrganizationServiceContext(serviceProxy1);
}

Answer

I had a similar problem with LINQ-to-CRM and went back to QueryExpressions because they worked, until I found the solution in some SDK sample while looking for something else: You need to add a ProxyTypesBehavior to your IOrganizationService object. I don't know what it does, but that definitely was the change that allowed me to use LINQ with the early bound classes (as I perceive it, LINQ-to-CRM can only be used with the early bound classes).

So the line you need after creating your IOrganizationService is:

organizationService.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior());

I hope that helps.