2010-08-27 82 views
1

我已經複製了我的代碼的精簡版,最近被重寫爲使用linq來訪問數據庫。優化C#中Linq的簡單使用方法

但是,在我看來,linq非常簡單,可能會進行相當多的優化,尤其是在foreach循環中存在linq語句的第90行。

看看別人怎麼會用linq編寫這個簡單的任務會非常有幫助。提前致謝!以下是我的源代碼片段。

// Model objects - these are to be populated from the database, 
// which has identical fields and table names. 
public class Element 
{ 
    public Element() 
    { 
     Translations = new Collection<Translation>(); 
    } 

    public int Id { get; set; } 
    public string Name { get; set; } 
    public Collection<Translation> Translations { get; set; } 

    public class Translation 
    { 
     public int Id { get; set; } 
     public string Title { get; set; } 
     public string Content { get; set; } 
     public Language Lang { get; set; } 
    } 
} 
public class Language 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public string Code { get; set; } 
} 

// Stripped-down functions for adding and loading Element 
// objects to/from the database: 

public static class DatabaseLoader 
{ 
    // Add method isn't too bulky, but I'm sure it could be optimised somewhere. 
    public static void Add(string name, Collection<Translation> translations) 
    { 
     using (var db = DataContextFactory.Create<ElementContext>()) 
     { 
      var dbElement = new Database.Element() 
      { 
       Name = name 
      }; 
      db.Elements.InsertOnSubmit(dbElement); 
      // Must be submit so the dbElement gets it's Id set. 
      db.SubmitChanges(); 

      foreach (var translation in translations) 
      { 
       db.Translations.InsertOnSubmit(
        new Database.Translation() 
         { 
          FK_Element_Id = dbElement.Id, 
          FK_Language_Id = translation.Lang.Id, 
          Title = translation.Title, 
          Content = translation.Content 
         }); 
      } 

      // Submit all the changes outside the loop. 
      db.SubmitChanges(); 
     } 
    } 

    // This method is really bulky, and I'd like to see the many separate linq 
    // calls merged into one clever statement if possible (?). 
    public static Element Load(int id) 
    { 
     using (var db = DataContextFactory.Create<ElementContext>()) 
     { 
      // Get the database object of the relavent element. 
      var dbElement = 
       (from e in db.Elements 
       where e.Id == id 
       select e).Single(); 

      // Find all the translations for the current element. 
      var dbTranslations = 
       from t in db.Translations 
       where t.Fk_Element_Id == id 
       select t; 

      // This object will be used to buld the model object. 
      var trans = new Collection<Translation>(); 

      foreach (var translation in dbTranslations) 
      { 
       // Build up the 'trans' variable for passing to model object. 
       // Here there is a linq statement for EVERY itteration of the 
       // foreach loop... not good (?). 
       var dbLanguage = 
        (from l in db.Languages 
        where l.Id == translation.FK_Language_Id 
        select l).Single(); 

       trans.Add(new Translation() 
        { 
         Id = translation.Id, 
         Title = translation.Title, 
         Content = translation.Content, 
         Language = new Language() 
          { 
           Id = dbLanguage.Id, 
           Name = dbLanguage.Name, 
           Code = dbLanguage.Code 
          } 
        }); 
      } 

      // The model object is now build up from the database (finally). 
      return new Element() 
       { 
        Id = id, 
        Name = dbElement.Name, 
        Translations = trans 
       }; 
     } 
    } 
} 
+0

@SO:我們需要自動行代碼樣本編號.... – 2010-08-27 14:37:11

+0

削減你的代碼示例到你想要的想法的幾個小塊,這許多代碼使它看起來像你只是想讓我們爲你做完整的重構。 – 2010-08-27 14:38:50

+0

@Jimmy Hoffa:對於長碼片段感到抱歉 - 我認爲向您展示整個上下文將有助於看到我的問題是什麼 - 嵌套的linq語句......但相信我,這是從項目的大量剝離代碼是真的。 – Greg 2010-08-27 15:06:59

回答

1

使用一些虛構的構造過於簡單化:

public static Element Load(int id) 
{ 
    using (var db = DataContextFactory.Create<ElementContext>()) 
    { 
     var translations = from t in db.Translations 
          where t.Fk_Element_Id == id 
          join l in db.Languages on t.FK_Language_Id equals l.Id 
          select new Translation(t, l); 

     return new Element(db.Elements.Where(x => x.Id == id).Single(), translations); 
    } 
} 
+0

這就是我所希望的那種 - 我不太確定lambda表達式是如何工作的,但是用你的例子我希望我能更快地學習。謝謝! – Greg 2010-08-27 15:27:02

0

我不喜歡這裏的第一件事是所有的「新譯(){BLA BLA =},因爲他們的代碼大塊,我會把他們的方法,其中你的手他們對象和他們返回新的給你。

Translations.InsertOnSubmit(CreateDatabaseTranslation(dbElement, translation)); 

trans.Add(CreateTranslationWithLanguage(translation, dbLanguage)); 

等,只要您有這樣的代碼,它只是muddles的你在這裏做什麼可讀性。