Linq到实体查询优化

本文关键字:查询优化 实体 Linq | 更新日期: 2023-09-27 17:58:43

我的数据库中有三个表,我正在使用它们:

  1. Theme [Theme_ID]
  2. ThemeWorkplace [Theme_ID, Workplace_ID, ThemeWorkplace_ID]
  3. UserTheme [User_ID, Theme_ID, UserTheme_ID, UserTheme_AccessType]

我需要用ThemeWorkplace.Workplace_ID = 2User_ID = 1更改当前工作场所中所有UserTheme.Theme_IDUserTheme_AccessType。如果主题在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);

在每次CCD_ 9迭代中。有人能帮帮我吗?

添加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);
}

Linq到实体查询优化

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

但在您的批处理命令中会有许多sql查询,因为EF会逐个生成用于更新实体的sql(而不是一个整体)。

若要更新数据库中的大量记录,则应该使用sql脚本(调用存储过程或执行sqlquery)来反对使用EntityFramework。

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

首先,选择ID等于2的工作场所。从该结果中,您可以选择主题ID。所有在前一个结果中出现主题ID的用户主题都将被选择为"用户主题"。从那里开始,你迭代结果,如果userID为空,你就创建一个新的UserTheme,否则你就更新它

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

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;
}