【问题标题】:Unable to cast the type 'Shared.ClientService' to type 'Shared.IClientID'. LINQ to Entities only supports casting EDM primitive or enumeration types无法将类型“Shared.ClientService”转换为类型“Shared.IClientID”。 LINQ to Entities 仅支持转换 EDM 基元或枚举类型
【发布时间】:2019-04-16 17:57:17
【问题描述】:

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

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

似乎它与连接有关,而不是与表格元素本身有关,但我不知道是什么。

如果我将代码拉出并内联函数,它会给出一个关于强制转换匿名类型的不同错误,这更没有意义。

【问题讨论】:

标签: c# linq casting


【解决方案1】:

正如 Clay 所指出的,解决方案是将“类”添加到所有 IQueryable&lt;T&gt; 函数声明中。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-29
    • 1970-01-01
    • 2011-03-14
    • 1970-01-01
    • 2013-03-13
    • 1970-01-01
    相关资源
    最近更新 更多