I made some changes to add a field to a table, and now I'm getting an exception on casting.
I've narrowed down the code as much as I can and still get the error.
My changes have been completely removed and I'm still getting the issue.
One question is, if it really is of type ClientService as it claims in the exception, how can it have an issue with casting to IClientID? There are nothing but primitive types involved that I can see.
In this code
try {
using (CFDb db = CreateDbContext<CFDb>(context)) {
ServiceFilter serviceFilter = filters.Where(f => f.ClassName == "ServiceFilter").Select(f => f).FirstOrDefault() as ServiceFilter;
IQueryable<ClientService> query = BuildServiceFilter(serviceFilter, db);
query = BuildClientGovernmentAssistanceFilter(query, (ClientGovernmentAssistanceFilter)null, db);
ClientService[] result = query.ToArray();
}
} catch (Exception ex) {
Logger.LogException("GetServicesReportData", ex, System.Diagnostics.TraceEventType.Error);
return null;
}
query.ToArray() throws
System.NotSupportedException: Unable to cast the type 'Shared.ClientService' to type 'Shared.IClientID'. LINQ to Entities only supports casting EDM primitive or enumeration types.
BuildClientGovernmentAssistanceFilter looks like this
private IQueryable<T> BuildClientGovernmentAssistanceFilter<T>(IQueryable<T> query, ClientGovernmentAssistanceFilter filter, CFPINDb db) where T : IClientID {
query = from clientService in query
join clientGovernmentAssistance in db.ClientGovernmentAssistance on clientService.ClientID equals clientGovernmentAssistance.ClientID
select clientService;
return query;
}
If I comment out the join, or the call to the routine, the error goes away.
I don't think it is an issue with the joined table per se because I can substitute any other table that supports IClientID and get the same error.
Note that T here is IClientID and is called as ClientService.
I can get BuildServiceFilter down to this:
private IQueryable<ClientService> BuildServiceFilter(ServiceFilter serviceFilter, CFPINDb db) {
query = from clientService in db.ClientServices
select clientService;
return query;
}
Here are the definitions:
public interface IClientID {
int ClientID { get; set; }
}
[DataContract]
public class ClientService : IClientID {
[DataMember]
public int ClientID { get; set; }
[DataMember]
public int ServiceID { get; set; }
[DataMember]
public DateTime ServiceDate { get; set; }
}
ClientService is slightly modified:
public DbSet<ClientService> ClientServices { get; set; }
modelBuilder.Entity<ClientService>().HasKey(k => new { k.ClientID, k.ServiceID, k.ServiceDate });
modelBuilder.Entity<ClientService>().Property(p => p.ClientID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
modelBuilder.Entity<ClientService>().Property(p => p.ClientID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
[DataContract]
public class ClientGovernmentAssistance: IClientID {
[DataMember, Key]
public int ClientGovernmentAssistanceID { get; set; }
[DataMember]
public int ClientID { get; set; }
}
It seems like it is something with the join, not with the table elements themselves, but I can't figure what.
If I pull the code out and inline the functions, it gives a different error about casting an anonymous type that makes even less sense.