I currently have a linq query that i use about 5 times within the same MVC class, is it possible to define the query somewhere within the page in the same way you can public const
a string
or an int
, without having to create a method which calls the linq query?
ie
const LinqQuery myQuery = from cat in db.Categories where cat.CategoryID != null select cat;
...
public ActionResult Edit(long id = 0)
{
ViewBag.ParentCategoryID = myQuery;
...
}
public ActionResult Create()
{
ViewBag.ParentCategoryID = myQuery;
...
}
From what i can see, the only way is creating a method, but i would like to avoid it if there is a nicer way of doing things.
My crystal ball tells me that Linq queries are only executed when you iterate over the result so:
static List<int> list = new List<int> { 1, 2, 3 };
static IEnumerable<int> result = from i in list where i > 2 select i;
static void Main(string[] args)
{
Console.WriteLine(result.Sum()); // 3
list.Add(5);
Console.WriteLine(result.Sum()); // 8
}
MSDN Has an article on precompiled queries:
http://msdn.microsoft.com/en-us/library/bb399335.aspx
In your example it could look something like this:
public static readonly Func<MyContext, int, IQueryable<Category>>
myQuery = CompiledQuery.Compile((MyContext db, int categoryID) =>
from cat in db.Categories where cat.CategoryID == categoryID select cat);
I added readonly
as it is going to be the closest you'll get to a constant.
Yes, just put it in the constructor (I assume the type of db.Catagories
is Catagory
)
public class ClassName
{
public ClassName()
{
db = //do whatever is needed to initialize the db context
myQuery = from cat in db.Categories where cat.CategoryID != null select cat;
}
DataSourceContext db;
IQueryable<Catagory> myQuery;
public ActionResult Edit(long id = 0)
{
ViewBag.ParentCategoryID = myQuery;
...
}
public ActionResult Create()
{
ViewBag.ParentCategoryID = myQuery;
...
}
}
This could also be done in the static constructor with static members if access to db
is done in a thread safe manner (via internally inside DataSourceContext
or by you in defensive coding)
However a better way would be to call a static function that returns the query you want and passing in the context of the database you want to connect to.
public static IQueryable<Catagory> NonNullCatagoriesQuery(DataSourceContext db)
{
return from cat in db.Categories where cat.CategoryID != null select cat;
}
Then in your code you just do
public ActionResult Edit(long id = 0)
{
ViewBag.ParentCategoryID = NonNullCatagoriesQuery(db);
...
}
public ActionResult Create()
{
ViewBag.ParentCategoryID = NonNullCatagoriesQuery(db);
...
}
You also could move the function in to a repository class that held the db context too so you would not need to pass it in, but you did not include in your code example how you got db
.
You're in luck, sorta, While it's similar, you can declare a Func<> and call that. It looks cleaner / nicer than a method when you only have a very simple instruction you want to execute.
Here's sorta an example on their implementation (This is from a project where I had to use SetWindowPos multiple times along with some other stuff):
Func<Process, winPosData, bool> swp = (p, w) => SetWindowPos(p.MainWindowHandle, (IntPtr)w.hWndInsertAfter, w.x, w.y, w.cx, w.cy, w.uFlags);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.