2011-03-06 88 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