无法将类型“ Shared.ClientService”强制转换为类型“ Shared.IClientID”。 LINQ to Entities仅支持转换EDM原语或枚举类型

时间:2019-04-16 17:57:18

标签: c# linq casting

我做了一些更改,将字段添加到表中,现在在转换时出现异常。
我已尽可能缩小代码范围,但仍然得到错误消息。
我的更改已被完全删除,但我仍然遇到问题。

一个问题是,如果它确实是异常中所声称的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; }
}

似乎与联接有关,与表元素本身无关,但我不知道是什么。

如果我拉出代码并内联函数,则在转换匿名类型时会给出不同的错误。

1 个答案:

答案 0 :(得分:0)

Clay指出,解决方案是将'class'添加到所有IQueryable<T>函数声明中。

    private IQueryable<T> ... where T : class, IClientID

我认为这行不通,因为在所有情况下,我都看到“类”解决方案朝着另一个方向发展,试图将类转换为类,而我的错误是将类转换为类接口。看起来它可以双向工作。