【问题标题】:What could cause a "This may indicate either a bug or a limitation in EF Core." error in a linq expression .net core 3.0?什么可能导致“这可能表明 EF Core 中存在错误或限制”。 linq 表达式.net core 3.0 中的错误?
【发布时间】:2020-09-04 22:37:27
【问题描述】:

我将应用程序的这一部分移植到使用 EF Core 检索数据库中的电子邮件模板,从 Web 表单到 .net core 3.0。我带来了下面的代码来实现这一点,所以我不必重写它,并且通过一些小的改动我让它编译,我假设相同的 linq 可以在这里工作,因为它们都是 EF。我猜不是,但我不确定从哪里开始。

public static class EmailTemplates
    {
        public static List<Template> GetClientEmailTemplates(Guid clientID)
        {
            DbContext db = new DbContext ();

            var templates = (from et in db.EmailTemplates
                             join cet in db.ClientEmailTemplates on et.EmailTemplateID equals cet.EmailTemplateID into leftJoinedTemplates
                             from ljt in leftJoinedTemplates.Where(ljt => ljt.ClientID == clientID).DefaultIfEmpty()
                             orderby et.DisplayOrder
                             select new Template
                             {
                                 EmailTemplateID = et.EmailTemplateID,
                                 PreferenceID = et.PreferenceID,
                                 Title = et.Title,
                                 ShortTitle = et.ShortTitle,
                                 Description = et.Description,
                                 Subject = (ljt.Subject == null) ? et.Subject : ljt.Subject,
                                 Body = (ljt.Body == null) ? et.Body : ljt.Body,
                                 DisplayOrder = et.DisplayOrder,
                                 IsDefaultTemplate = (ljt == null)
                             }).ToList();

            List<KeyValuePair<int, string>> preferences = Preferences.GetPreferences(clientID, templates.Select(t => t.PreferenceID).ToList());
            foreach (KeyValuePair<int, string> preference in preferences)
            {
                bool enabled = false;
                try { enabled = Convert.ToBoolean(preference.Value); }
                catch { }

                if (!enabled) templates.Remove(templates.Where(t => t.PreferenceID == preference.Key).FirstOrDefault());
            }

            return templates;
        }

        public static Template GetClientEmailTemplate(Guid clientID, int emailTemplateID)
        {
            ImperiumDataContext db = new ImperiumDataContext();

            var template = (from et in db.EmailTemplates
                            join cet in db.ClientEmailTemplates on et.EmailTemplateID equals cet.EmailTemplateID into leftJoinedTemplates
                            from ljt in leftJoinedTemplates.Where(ljt => ljt.ClientID == clientID).DefaultIfEmpty()
                            orderby et.DisplayOrder
                            where et.EmailTemplateID == emailTemplateID
                            select new Template
                            {
                                EmailTemplateID = et.EmailTemplateID,
                                PreferenceID = et.PreferenceID,
                                Title = et.Title,
                                ShortTitle = et.ShortTitle,
                                Description = et.Description,
                                Subject = (ljt.Subject == null) ? et.Subject : ljt.Subject,
                                Body = (ljt.Body == null) ? et.Body : ljt.Body,
                                DisplayOrder = et.DisplayOrder,
                                IsDefaultTemplate = (ljt == null)
                            }).FirstOrDefault();

            if (Preferences.GetBoolPreference(clientID, template.PreferenceID))
            {
                return template;
            }

            return null;
        }
    }```

【问题讨论】:

标签: c# linq asp.net-core entity-framework-core


【解决方案1】:

尝试删除.DefaultIfEmpty 看看它是否有效。如果可行,请记住,EF Core 会用 Inner Join 代替 Left Join 来转换您的查询,您必须解决此问题。

根据issue #14902 看来,在 3.1 之前,EF Core 无法将 .DefaultIfEmpty 转换为 SQL。

如果您无法升级您的版本,我建议您尝试使用导航属性,例如this post

类似:

 (from et in db.EmailTemplates
                             join cet in db.ClientEmailTemplates on et.EmailTemplateID equals cet.EmailTemplateID into leftJoinedTemplates
                             from ljt in leftJoinedTemplates.Where(ljt => ljt.ClientID == clientID)
                             orderby et.DisplayOrder
                             select new Template
                             {
                                 EmailTemplateID = et.EmailTemplateID,
                                 PreferenceID = et.PreferenceID,
                                 Title = et.Title,
                                 ShortTitle = et.ShortTitle,
                                 Description = et.Description,
                                 Subject = ljt.Select(x => x.Subject).FirstOrDefault(),
                                 Body = ljt.Select(x => x.Body).FirstOrDefault(),
                                 DisplayOrder = et.DisplayOrder,
                                 IsDefaultTemplate = !ljt.Any()
                             }).ToList();

如果它仍然不起作用,我建议尽可能发布完整的异常。通常,异常包含一些关于可能出错的线索。

【讨论】:

    猜你喜欢
    • 2020-06-13
    • 2020-11-09
    • 2021-08-30
    • 2011-09-02
    • 2020-03-08
    • 2022-11-11
    • 2018-12-25
    • 2011-01-07
    • 1970-01-01
    相关资源
    最近更新 更多