2013-02-12 45 views
0

我在DB 3个表内,以我的工作:LINQ到实体查询优化

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

我需要改变UserTheme_AccessType所有UserTheme.Theme_ID在当前工作场所与ThemeWorkplace.Workplace_ID = 2User_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()的代码:

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); 
} 
+1

这可能是张贴的GetByUserTheme'如何'工作机制的细节是有用的。 – 2013-02-12 11:36:05

+0

谢谢,我已经添加了GetByUserTheme声明。 – 2013-02-12 11:45:48

回答

0

第一:你在代码中也做了实体的所有更改会在一个批处理命令推到数据库当你拨打context.SaveChanges。所以你将有一个请求数据库选择和一个更新请求。

但在你的批处理命令,将成为事业EF许多SQL查询生成更新实体逐一SQL(而不是在一个所有)。

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

+0

感谢您的解释。我认为研究Entity freamework以了解它如何在内部深处起作用更好。 – 2013-02-12 13:40:07

0

我不知道如果我完全理解你的问题和结构。但基于我所看到的,这可能是一个合理的解决方案吗?

首先,选择具有ID等于2。从该结果对工作场所选择的主题-ID的。然后,所有具有以前结果中出现的themeID的用户将被选入'userThemes'。从那里开始迭代结果,如果用户标识为空,则创建一个新的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; 
}