c# - 无法创建类型为 'Anonymous type' 的常量值。在此上下文中仅支持原始类型或枚举类型

标签 c# .net linq entity-framework linq-to-sql

我对 linq 和 Entity Framework 非常陌生。我正在尝试解决以下问题为何不起作用的问题。产生的错误是“无法创建‘匿名类型’类型的常量值。在此上下文中仅支持原始类型或枚举类型。”

我已经尝试了很多不同的方法,但仍然遇到与原始类型相关的错误。如果有人可以看一下下面的代码并希望指出哪里出了问题,我将不胜感激。

        public Entities.BikeData[] GetBikesWithExpiredSyncDeadline(int noOfDays) {

        using (OfficeEntities cxt = GetContext()) 
        using (ReportingEntities RepCxt = GetReportingContext()) {
            Data.Repository.Abstract.IBikeRepository BikeRepos = new Data.Repository.Concrete.BikeRepository();                

            var details = (from sd in cxt.BikeDetails
                                        where sd.autoreminder == true
                                            && (sd.lastremindersent == null || sd.lastremindersent < EntityFunctions.AddDays(DateTime.UtcNow, noOfDays * -1))
                                            && (sd.emailaddress != null && sd.emailaddress.Trim() != "")
                                        select new {
                                            Serial = sd.Serial,
                                            EmailAddress = sd.emailaddress
                                        }).ToList();

            var resLst = (from r in RepCxt.RegisteredBikes
                          join d in details on r.Serial equals d.Serial 
                          join cs in cxt.CompanySettings.ToList() on r.CompanyID equals cs.CompanyID
                          where (!r.lastupdate.HasValue || r.lastupdate < EntityFunctions.AddDays(DateTime.UtcNow, cs.AutoNotificationFrequency * -1))
                          select new Entities.BikeData {
                              ID = r.ID,
                              Name = r.Ship,
                              Serial = r.Serial,
                              LastUpdate = r.lastupdate,
                              DaysSinceLastSync = (r.lastupdate.HasValue? EntityFunctions.DiffDays(r.lastupdate.Value, DateTime.UtcNow).Value : -1),
                              EmailAddress = (d.EmailAddress == null ? string.Empty : (String.IsNullOrEmpty(d.EmailAddress) ? r.ShipEmailAddress : d.EmailAddress))
                          });

            return resLst.ToArray();
        }
    }

更新

我现在通过创建一个 View 对此采取了不同的方法,因此我不再需要在 EF 中进行跨上下文连接。我希望您能在以下方面提供帮助。

当我运行 objectQuery.ToTraceString() 时,它为我提供了返回数据库中记录的有效 SQL,但是 EntityFramework 中的 resLst 总是返回 0。关于为什么会发生这种情况有什么明显的吗?

  var resLst = (from ls in cxt.BikeLastUpdates
                          where (!ls.lastupdate.HasValue || ls.lastupdate < EntityFunctions.AddDays(DateTime.UtcNow, ls.AutoNotificationFrequency * -1))
                          && (ls.autoreminder ==true)
                          && (ls.lastremindersent == null || ls.lastremindersent < EntityFunctions.AddDays(DateTime.UtcNow, 3 * -1))
                          && (ls.emailaddress !=null && ls.emailaddress.Trim() != "")
                          select new Entities.BikeData{
                              ID = (ls.ID ?? new Guid()),
                              Name = ls.Bike,
                              Serial = ls.Serial,
                              LastUpdate = ls.lastupdate,
                              EmailAddress = (String.IsNullOrEmpty(ls.emailaddress) ?  ls.ShipEmailAddress : ls.emailaddress)
                          });

            var objectQuery = resLst as ObjectQuery;

            return resLst.ToArray();

最佳答案

问题是 ToList() 对细节的调用。在 EF 中,如果 IEnumerable 是简单类型(例如 int),则只能在查询中引用 IEnumerable。但是,您可以引用另一个 IQueryable。因此,删除 ToList() 调用应该可以完成这项工作。

编辑:同样,您应该放弃对 ctx.CompanySettings 的 ToList() 调用。

这将具有仅执行 1 个查询而不是 2 个查询的额外优势。如果将 ToList() 放在 details 上,EF 将生成如下内容:

SELECT ...
FROM RegisteredBikes rb
JOIN (
    /* this is your "details" IQueryable */
    SELECT Serial, EmailAddress
    FROM BikeDetails
    WHERE ...
) bd
    ON rb.Serial = b.Serial
JOIN CompanySettings cs
    ON ...
WHERE ...

编辑:要跨上下文执行此操作,您需要将查询带入内存(例如,通过调用 AsEnumerable() 并在那里进行相关的连接。如果连接充当过滤器并且这些在 SQL 中发生很重要,考虑使用 Contains()。例如

var serials = details.Select(d => d.Serial);
var filtered = RepCtxt.RegisteredBikes.Where(r => details.Contains(r.Serial);

关于c# - 无法创建类型为 'Anonymous type' 的常量值。在此上下文中仅支持原始类型或枚举类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18013855/

相关文章:

c# - C# 数据类型大小是固定的还是可变的?

c# - Brighter Consumer 消息未路由到处理程序

c# - 在 C# 中为 Xamarin 禁用泛型

c# - 使用 IQueryable 创建动态查询

c# - 如何合并 Generic.Collection.List 和 Generic.Collection.Dictionary

c# - 在 C# 中获取系统时钟更改滴答

c# - 实现IDataErrorInfo接口(interface)时 `public string this[string columnName]`是什么意思?

c# - 有没有办法使用linq to sql批量插入

.net - System.Xml 是否使用 MSXML?

C#:如何知道是否安装了某个Office 2003或2007应用程序?