C# Linq到实体查询优化

C# Linq到实体查询优化,c#,optimization,linq-to-entities,C#,Optimization,Linq To Entities,我的数据库中有3个我正在使用的表: Theme[Theme\u ID] ThemeWorkplace[主题标识、工作场所标识、ThemeWorkplace标识] UserTheme[User\u ID,Theme\u ID,UserTheme\u ID,UserTheme\u AccessType] 我需要为所有UserTheme.Theme\u ID用户主题更改UserTheme\u AccessType,当前工作场所的ThemeWorkplace.workplace\u ID=2和当前用户的

我的数据库中有3个我正在使用的表:

  • Theme[Theme\u ID]
  • ThemeWorkplace[主题标识、工作场所标识、ThemeWorkplace标识]
  • UserTheme[User\u ID,Theme\u ID,UserTheme\u ID,UserTheme\u AccessType]
  • 我需要为所有
    UserTheme.Theme\u ID
    用户主题更改
    UserTheme\u AccessType
    ,当前工作场所的
    ThemeWorkplace.workplace\u ID=2
    和当前用户的
    user\u ID=1
    。如果主题在
    UserTheme
    中不存在,那么我需要创建它

    我写了这样一个代码,但它工作时间太长:

    var themeList = (from t in m_Entities.Theme
                        where (from tw in m_Entities.ThemeWorkplace
                            where tw.Workplace.Workplace_ID == 2
                            select tw.Theme.Theme_ID).Contains(t.Theme_ID)
                                select t)
                    .ToList();
    
    foreach (Theme theme in themeList)
    {
        var oldUserTheme = GetByUserTheme(user/*user is given*/, theme);
    
        if (oldUserTheme == null)
        {
            /* create new User Theme with params, that I need*/
            this.Add(newUserTheme, true);
        }
        else
        {
            /* here - changing found row */
            oldUserTheme.UserTheme_AccessType = 2;
        }
    }
    
    我知道这段代码访问数据库的次数太多了。我想找到一种方法来摆脱:

    var oldUserTheme = GetByUserTheme(user/*user is given*/, theme);
    
    在每次
    foreach
    迭代中。谁能帮帮我吗

    正在添加GetByUserTheme()的代码:


    我不知道我是否完全理解你的问题和结构。但根据我所看到的,这是一个合理的说法吗

    首先,选择ID等于2的工作场所。从该结果中选择主题ID。所有在前一个结果中出现themeID的userthemes将被选择到“userthemes”中。从那里,您迭代结果,如果userID为空,您将创建一个新的UserTheme,否则将更新它

    快速提示:下面的代码不是真正的工作代码。我写的代码只是为了举例说明我的解释,如果你愿意的话,这是一种伪代码:)


    第一:当您调用
    context.SaveChanges
    时,您在代码中对实体所做的所有更改都将在一个批处理命令中推送到数据库中。所以,您将有一个数据库选择请求和一个更新请求

    但在批处理命令中会有许多sql查询,因为EF会逐个(而不是全部)为更新实体生成sql


    如果您想更新数据库中的许多记录,应该使用sql脚本(调用存储过程或执行sqlquery)来对抗EntityFramework。

    发布
    GetByUserTheme
    工作原理的详细信息可能会很有用。谢谢,我添加了GetByUserTheme语句。谢谢您的解释。我认为对我来说,最好是研究实体工作,了解它是如何在内心深处运作的。
    private UserTheme GetByUserTheme(User user, Theme theme)
    {
        return m_Entities.UserTheme.FirstOrDefault(ut => ut.User.User_ID == user.User_ID && ut.Theme.Theme_ID == theme.Theme_ID);
    }
    
    var userThemes = entities.Userthemes
                             .Where(ut => entities.Workplaces
                                                  .Where(w => w.WorkPlaceID == 2)
                                                  .Select(s => s.ThemeID)
                                                  .Contains(ut.ThemeID));
    
    foreach (UserTheme ut in userThemes)
    {
        if (ut.UserID.ToString() == "")
        {
            //Create
        }
        else
            ut.UserThemeAccessType = 2;
    }