Linq Scope Problem + Reduce Repeated Code
If the parameter is -1, it needs to run a different query as to if an ID was specified... how do I do this? I've tried initialising var q; outside the If block but no luck!
// 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;
}
}
My main aim is to reduce repeating code
Edit
As per some answers I've now got:
// 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;
}
}
}
This works, but throws a lot of blue squiggly lines in VS, and
this.ThisEntry.Username = q.Username;
Outputs in HTML to:
{ DisplayName = Tom }
Not just 'Tom' as I want it to!
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()
}
}
Try
/ 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;
}
}
}
There are two issues with your your code the way t is. First, since you are only selecting ONE object, you shouldn't declare q as an IEnumerable. You could do that if you selected a range.
Second, since you are going to get a single tblBlogEntry object, you should declare Q as such, but then you should not select the object with a NEW, because this will make it an anonymous object and you will get the "CS0029: Cannot implicitly convert type 'AnonymousType#1' to 'tblBlogEntry'" error
you need to just select it as a tblBlogEntry. If however, you do not want to bring the whole object with the query, or need to add more fields that you dont have on tblBlogEntry, you should create a new class that has only the attributes that you need and then you can create a new instance of that class:
Bringing the whole object with ALL its fields:
// 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;
}
}
}
Bringing the just some specific fields, or with fields that the object doesnt have:
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;
}
}
}
精彩评论