我做了一些更改,将字段添加到表中,现在在转换时出现异常。
我已尽可能缩小代码范围,但仍然得到错误消息。
我的更改已被完全删除,但我仍然遇到问题。
一个问题是,如果它确实是异常中所声称的ClientService类型,那么如何将其转换为IClientID会有问题?我可以看到的只是原始类型。
在此代码中
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()引发
System.NotSupportedException:无法将类型“ Shared.ClientService”强制转换为类型“ Shared.IClientID”。 LINQ to Entities仅支持强制转换EDM基本类型或枚举类型。
BuildClientGovernmentAssistanceFilter看起来像这样
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;
}
如果我注释掉联接或例程的调用,错误就会消失。
我认为联接表本身不是问题,因为我可以替换支持IClientID的任何其他表并得到相同的错误。
注意,这里的T是IClientID,被称为ClientService。
我可以将BuildServiceFilter简化为:
private IQueryable<ClientService> BuildServiceFilter(ServiceFilter serviceFilter, CFPINDb db) {
query = from clientService in db.ClientServices
select clientService;
return query;
}
以下是定义:
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稍作修改:
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; }
}
似乎与联接有关,与表元素本身无关,但我不知道是什么。
如果我拉出代码并内联函数,则在转换匿名类型时会给出不同的错误。
答案 0 :(得分:0)
Clay指出,解决方案是将'class'添加到所有IQueryable<T>
函数声明中。
private IQueryable<T> ... where T : class, IClientID
我认为这行不通,因为在所有情况下,我都看到“类”解决方案朝着另一个方向发展,试图将类转换为类,而我的错误是将类转换为类接口。看起来它可以双向工作。