Linq到实体查询优化

时间:2013-02-12 10:56:46

标签: c# optimization linq-to-entities

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

  1. Theme [Theme_ID]
  2. ThemeWorkplace [Theme_ID, Workplace_ID, ThemeWorkplace_ID]
  3. UserTheme [User_ID, Theme_ID, UserTheme_ID, UserTheme_AccessType]
  4. 我需要使用UserTheme_AccessType更改当前工作区中所有UserTheme.Theme_ID的{​​{1}}和ThemeWorkplace.Workplace_ID = 2的当前用户。如果主题在User_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); 次迭代中。有人可以帮帮我吗?

    添加GetByUserTheme()的代码:

    foreach

2 个答案:

答案 0 :(得分:0)

我不知道我是否完全理解你的问题和结构。但根据我的看法,这可能是一个合理的洗脱吗?

首先选择ID等于2的工作场所。从该结果中选择主题ID。所有具有在前一个结果中出现的themeID的用户标题将被选择为“用户主题”。从那里,你迭代结果,如果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;
}

答案 1 :(得分:0)

首先:当您致电context.SaveChanges时,您在代码中完成的实体的所有更改都将在一个批处理命令中推送到数据库。因此,您将有一个请求数据库的select和一个请求更新。

但是在你的批处理命令中会有很多sql查询,因为EF会逐个生成用于更新实体的sql(不是全部在一起)。

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