2011-03-06 87 views
0

如果參數爲-1,則需要運行不同的查詢以確定是否指定了ID ......我該怎麼做?我試過初始化var q;在If塊之外,但沒有運氣!Linq作用域問題+減少重複代碼

// Loads by Entry ID, or if -1, by latest entry 
private void LoadEntryByID(int EntryID) 
{ 
    IEnumerable<tblBlogEntry> q; 
    if (EntryID == -1) 
    { 
     q = (
      from Blog in db.tblBlogEntries 
      orderby Blog.date descending 
      select new 
      { 
       Blog.ID, 
       Blog.title, 
       Blog.entry, 
       Blog.date, 
       Blog.userID, 
       Comments = (
        from BlogComments in db.tblBlogComments 
        where BlogComments.blogID == Blog.ID 
        select BlogComments).Count(), 
       Username = (
        from Users in db.yaf_Users 
        where Users.UserID == Blog.userID 
        select new { Users.DisplayName }) 
      }).FirstOrDefault(); 
    } 
    else 
    { 
     q = (
      from Blog in db.tblBlogEntries 
      where Blog.ID == EntryID 
      select new 
      { 
       Blog.ID, 
       Blog.title, 
       Blog.entry, 
       Blog.date, 
       Blog.userID, 
       Comments = (
        from BlogComments in db.tblBlogComments 
        where BlogComments.blogID == Blog.ID 
        select BlogComments).Count(), 
       Username = (
        from Users in db.yaf_Users 
        where Users.UserID == Blog.userID 
        select new { Users.DisplayName }) 
      }).SingleOrDefault(); 
    } 
    if (q == null) 
    { 
     this.Loaded = false; 
    } 
    else 
    { 
     this.ID = q.ID; 
     this.Title = q.title; 
     this.Entry = q.entry; 
     this.Date = (DateTime)q.date; 
     this.UserID = (int)q.userID; 
     this.Loaded = true; 
     this.AuthorUsername = q.Username; 
    }  
} 

我的主要目的是減少重複的代碼

編輯

按照一些答案我現在已經有了:

// Blog data model 
public class EntryModel 
{ 
    public int ID { get; set; } 
    public string Title { get; set; } 
    public string Entry { get; set; } 
    public DateTime Date { get; set; } 
    public int UserID { get; set; } 
    public string Username { get; set; } 
    public int Comments { get; set; } 
} 

// A single blog entry 
public class BlogEntry 
{ 
    public bool Loaded;  // Did this entry load OK? 
    private DataClassesDataContext db = new DataClassesDataContext(); 
    public EntryModel ThisEntry = new EntryModel(); 

    // Initialisers 
    public BlogEntry(int EntryID) 
    { 
     this.LoadEntryByID(EntryID); 
    } 
    public BlogEntry() 
    { 
     this.LoadLatest(); 
    } 
    public void LoadLatest() 
    { 
     this.LoadEntryByID(-1); 
    }  

    // Loads by Entry ID, or if -1, by latest entry 
    private void LoadEntryByID(int EntryID) 
    { 
     EntryModel q = null; 
     if (EntryID == -1) 
     { 
      q = (from Blog in db.tblBlogEntries 
       orderby Blog.date descending 
       select new EntryModel 
       { 
        Title = Blog.title, 
        ID = Blog.ID, 
        Entry = Blog.entry, 
        Date = (DateTime)Blog.date, 
        UserID = (int)Blog.userID, 
        Comments = (from BlogComments in db.tblBlogComments where BlogComments.blogID == Blog.ID select BlogComments).Count(), 
        Username = (from Users in db.yaf_Users where Users.UserID == Blog.userID select new { Users.DisplayName }).SingleOrDefault().ToString() 
       } 
       ).FirstOrDefault(); 
     } 
     else 
     { 
      q = (from Blog in db.tblBlogEntries 
        where Blog.ID == EntryID 
        select new EntryModel 
        { 
         Title = Blog.title, 
         ID = Blog.ID, 
         Entry = Blog.entry, 
         Date = (DateTime)Blog.date, 
         UserID = (int)Blog.userID, 
         Comments = (from BlogComments in db.tblBlogComments where BlogComments.blogID == Blog.ID select BlogComments).Count(), 
         Username = (from Users in db.yaf_Users where Users.UserID == Blog.userID select new { Users.DisplayName }).SingleOrDefault().ToString() 
        }).SingleOrDefault(); 
     } 
     if (q == null) 
     { 
      this.Loaded = false; 
     } 
     else 
     {    
      this.ThisEntry.ID = q.ID; 
      this.ThisEntry.Title = q.Title; 
      this.ThisEntry.Entry = q.Entry; 
      this.ThisEntry.Date = q.Date; 
      this.ThisEntry.UserID = q.UserID; 
      this.Loaded = true; 
      this.ThisEntry.Username = q.Username; 
      this.ThisEntry.Comments = q.Comments; 
     }  
    } 
} 

這工作,但拋出了很多VS中的藍色波浪線,以及

this.ThisEntry.Username = q.Username; 

輸出在HTML中:

{顯示名稱=湯姆}

不只是 '湯姆',因爲我希望它!

+0

在IEnumerable 之外重新定義塊之外的塊? – CarneyCode 2011-03-06 15:37:05

+0

作爲一般說明,我將這兩個作爲截然不同的呼叫,而是有一個if/else somehwere。這樣,商業意義後來就很清楚了,而不是隱含的「-1意味着最新的條目」 – Larsbj 2011-03-06 15:47:27

+0

這段代碼不會編譯。您試圖將一個匿名類型的IEnumerable賦值給IEnumerable 類型的變量'q'。此外(如果編譯代碼),代碼'this.Loaded = false;'永遠不會被調用,因爲'q'總是有一個值。 – Steven 2011-03-06 16:03:40

回答

2
tblBlogEntry myBlog; 
if (EntryID != -1) 
{ 
    myBlog = db.tblBlogEntries 
      .SingleOrDefault(blog => blog.ID == EntryID); 
} 
else 
{ 
    myBlog = db.tblBlogEntries 
      .OrderByDescending(blog => blog.date).FirstOrDefault(); 
} 

this.Loaded = myBlog != null; 

if (this.Loaded) 
{ 
    this.ThisEntry = new EntryModel 
    { 
    ID = myBlog.ID, 
    Title = myBlog.title, 
    Entry = myBlog.entry, 
    Date = (DateTime)myBlog.date, 
    UserID = (int)myBlog.userID, 
    Username = db.yaf_Users 
       .Single(user => user.UserID == myBlog.userID).DisplayName, 
    Comments = db.tblBlogComments 
       .Where(comment => comment.blogID == myBlog.ID).Count() 
    } 
} 
+0

+1用於減少重複性代碼。通過使用SingleOrDefault/FirstOrDefault,應該爲'null'檢查'q'。 – 2011-03-06 16:34:42

+0

真棒的回答,正是我要找的 – 2011-03-06 16:48:09

+0

不客氣。我喜歡LINQ擴展方法比語言結構更好,因爲在我看來,它們導致更簡潔的代碼並更好地理解它的工作原理。 – Jan 2011-03-06 17:02:12

2

嘗試

/ Loads by Entry ID, or if -1, by latest entry 
private void LoadEntryByID(int EntryID) 
{ 
    dynamic q = null; 
    if (EntryID == -1) 
    { 
     q = (from Blog in db.tblBlogEntries 
      orderby Blog.date descending 
      select new 
      { 
       Blog.ID, 
       Blog.title, 
       Blog.entry, 
       Blog.date, 
       Blog.userID, 
       Comments = (from BlogComments in db.tblBlogComments where BlogComments.blogID == Blog.ID select BlogComments).Count(), 
       Username = (from Users in db.yaf_Users where Users.UserID == Blog.userID select new { Users.DisplayName }).SingleOrDefault() 
      }).FirstOrDefault(); 
    } 
    else 
    { 
     q = (from Blog in db.tblBlogEntries 
       where Blog.ID == EntryID 
       select new 
       { 
        Blog.ID, 
        Blog.title, 
        Blog.entry, 
        Blog.date, 
        Blog.userID, 
        Comments = (from BlogComments in db.tblBlogComments where BlogComments.blogID == Blog.ID select BlogComments).Count(), 
        Username = (from Users in db.yaf_Users where Users.UserID == Blog.userID select new { Users.DisplayName }).SingleOrDefault() 
       }).SingleOrDefault(); 
    } 
    if (q == null) 
    { 
     this.Loaded = false; 
    } 
    else 
    { 
     this.ID = q.ID; 
     this.Title = q.title; 
     this.Entry = q.entry; 
     this.Date = (DateTime)q.date; 
     this.UserID = (int)q.userID; 
     this.Loaded = true; 
     this.AuthorUsername = q.Username.DisplayName; 
    }  
} 

}

+0

CS0029:不能將類型'AnonymousType#1'隱式轉換爲'tblBlogEntry'。我已經將類型更改爲tblBLogEntry,並且我已將屬性字段添加到Linq顯示的註釋中,但在這裏沒有任何運氣,只是試圖減少您看到的重複代碼。 – 2011-03-06 15:42:27

+0

@Tom如果您使用的是C#4。0我想你可以嘗試'動態q' – 2011-03-06 15:45:50

+0

我已經更新了問題 – 2011-03-06 15:45:57

1

有你的代碼t時的方式是兩個問題。首先,由於您只選擇了一個對象,因此不應將q聲明爲IEnumerable。如果你選擇了一個範圍,你可以這樣做。

其次,既然你要得到一個單一的tblBlogEntry對象,你應該聲明Q是這樣的,但是你不應該選擇帶有NEW的對象,因爲這會使它成爲一個匿名對象,你將得到"CS0029: Cannot implicitly convert type 'AnonymousType#1' to 'tblBlogEntry'" error你只需要選擇它作爲tblBlogEntry。但是,如果您不希望將整個對象與查詢結合使用,或者需要添加更多不包含在tblBlogEntry中的字段,則應該創建一個僅具有所需屬性的新類,然後您可以創建一個新類

使整個物體ALL其字段:該類的實例

// Loads by Entry ID, or if -1, by latest entry 
    private void LoadEntryByID(int EntryID) 
    { 
     tblBlogEntry q; 
     if (EntryID == -1) 
     { 
      q = (from Blog in db.tblBlogEntries 
       orderby Blog.date descending 
       select Blog).SingleOrDefault(); 
     } 
     else 
     { 
      q = (from Blog in db.tblBlogEntries 
        where Blog.ID == EntryID 
        select Blog).SingleOrDefault(); 
     } 
     if (q == null) 
     { 
      this.Loaded = false; 
     } 
     else 
     { 
      this.ID = q.ID; 
      this.Title = q.title; 
      this.Entry = q.entry; 
      this.Date = (DateTime)q.date; 
      this.UserID = (int)q.userID; 
      this.Loaded = true; 
      this.AuthorUsername = q.Username; 
     }  
    } 
} 

瞻只是一些具體領域,或與該對象可是沒有字段:

public class EntryModel 
{ 
    public int ID {get;set;} 
    public string Title {get;set;} 
    public string Entry{get;set;} 
    public DateTime Date {get;set;} 
    public int UserID {get;set;} 
    public List<Comment> Comments {get;set;} 
} 
// Loads by Entry ID, or if -1, by latest entry 
private void LoadEntryByID(int EntryID) 
{ 
    EntryModel q; 
    if (EntryID == -1) 
    { 
     q = (from Blog in db.tblBlogEntries 
     orderby Blog.date descending 
     select select new EntryModel() 
     { 
      ID=Blog.ID, 
      Title=Blog.title, 
      Entry=Blog.entry, 
       Date=Blog.date, 
       UserId=Blog.userID, 
       Comments = (from BlogComments in db.tblBlogComments where  BlogComments.blogID == Blog.ID select BlogComments).Count() 
      }).SingleOrDefault(); 
     } 
     else 
     { 
      q = (from Blog in db.tblBlogEntries 
        where Blog.ID == EntryID 
        select select new EntryModel() 
      { 
       ID=Blog.ID, 
       Title=Blog.title, 
       Entry=Blog.entry, 
       Date=Blog.date, 
       UserId=Blog.userID, 
       Comments = (from BlogComments in db.tblBlogComments where  BlogComments.blogID == Blog.ID select BlogComments).Count() 
      }).SingleOrDefault(); 
     } 
     if (q == null) 
     { 
      this.Loaded = false; 
     } 
     else 
     { 
      this.ID = q.ID; 
      this.Title = q.title; 
      this.Entry = q.entry; 
      this.Date = (DateTime)q.date; 
      this.UserID = (int)q.userID; 
      this.Loaded = true; 
      this.AuthorUsername = q.Username; 
     }  
    } 
} 
+0

嗨,謝謝你的回答,我喜歡這種方法,我認爲John Skeet推薦了類似的東西。我已經更新了我的答案,但我得到了很多藍色的波浪線,並且用戶名也沒有正確渲染。 – 2011-03-06 16:44:03

+0

用戶名是什麼類型?爲什麼不僅僅是一個字符串,所以當你做linq查詢時,你只需選擇值而不必創建一個新的用戶名類? – 2011-03-06 17:38:10