Calling controller Action method using lambda expressions - c#

I am trying to call a controller action method inside the lambda expression like below.
Here dtImporteddata is my DataTable
public class DepartmentController : Controller
{
public ActionResult Create(FormCollection collection, int ParentDepartmentID)
{
return view();
}
}
dtImporteddata.Rows.Cast<DataRow>().Select(r => new DepartmentController().Create(new FormCollection{
{"ParentDepartmentID","57"},
{"DepartmentPrefix",r["Prefix"].ToString()},
{"DepartmentID","0"},
{"IsSpecialDepartment",null},
{"Description",r["Description"].ToString()},
{"Name",r["Name"].ToString()},
{"LocationIDs.$.PackedValue","4;;;"}
}, 0)).ToList();
if i write like above the Create() method is getting called perfectly but if i remove ToList() then the Create() is not getting called.

The problem is that the Select method actually doesn't do that much. It starts doing something when you iterate over its result.
That said, the ToList method does iterate over the iterator returned from Select, hence it executes your lambda expression.
I guess you want to pick up the result and do something with it, if so, assign it to a variable and iterate over it:
foreach(var row in dtImporteddata.Rows.Cast<DataRow>().Select(...))
{
// do something with row
}

LINQ methods can be split into two camps: those which always return a result (eg, FirstOrDefault) and those which project a different form of what's being given to them. You can think of these projection methods as performing filtering operations.
See what is a projection in LINQ, as in .Select()
Anyway, to answer your question, LINQ doesn't always perform the operation that you might think it's performing. In many cases LINQ uses subsequent operations to add filtering (or modify the projection) and only when you resolve the method call to a result are the calls executed.
I suspect that this is the case here. Without the ToList call you're only building the set of instructions, and only when you call ToList are these instructions resolved to a result.
If you're not actually bothered about the functionality offered by a List<DataRow> and you simply want an enumerable result, consider using ToArray as it has less overhead than ToList.

I would suggest abstracting the create functionality in a reusable component, that both the controller and your lambda can use. For example, you could create a class that has a method with the following signature:
public void CreateDepartment(Department newDepartment)
The Department class could probably expose the same fields as the FormCollection.
You could the use the new method directly in LINQ like so:
dtImporteddata.Rows.Cast<DataRow>().ToList()
.ForEach(r => CreateDepartment(
new Department {
Name = r.Name,
....//rest of the properties
}));
In this way, you would also be able to call the same method within the Create action.

Related

Usage of EntityFrameworkQueryableExtensions.ThenInclude in EF Core

I tried to define a generic loading method.
I call this generic loading method with an array of expressions like this:
var includes = new Expression<Func<CatalogItem, object>>[]
{
ci => ci.Catalog.Select(ci => ci.Supplier.Region),
ci => ci.Test
}
In the method I create an IQueryable:
IQueryable<TAggregateRoot> queryable = dbContext.Set<TAggregateRoot>();
Then for each Expression I want to load the respective data like this:
foreach (var include in includes)
{
queryable = queryable.Include(include);
}
But this only works when the Expression is only one level. With multiple levels it throws an error.
Since there is no ThenInclude I have to use the EntityFrameworkQueryableExtensions. I tried it like this
queryable = EntityFrameworkQueryableExtensions.ThenInclude(queryable, include);
But this does not work either.
I cannot find any documentation to this problem. How do I solve this problem and how do I use EntityFrameworkQueryableExtensions.ThenInclude?
Instead of passing an expression to the Include() method, there are two overloads you can use that take strings.
The first takes either a single property or multi-level properties like so:
Include("property1")
OR
Include("property1.property2.property3")
The second takes advantage of the nameof() method like so:
Include(nameof(property1), nameof(property2), nameof(property3))
And if you have a generic loading method that takes an array of strings to iterate over and "Include" (in precisely the same fashion you are iterating over your array right now), then you can use the first overload (one string) and do something like this:
MyGenericRepo.MySetInclude(new string[] {$"{nameof(ParentEntity.ChildEntity)}.{nameof(ChildEntity.GrandchildEntity)}"});
So you are still only using the one Include() method without adding any additional logic to your repository, but you can now "include" as many levels as you wish.
To see the origins of these overloads, you can check it out here

Need help figuring out what this C# code does

I am going through a tutorial for asp.net and C# and the author used some code that I am trying to understand. I have an idea of what it does, but I just wanted to make sure.
public IQueryable<Category> GetCategories()
{
var db = new WingtipToys.Models.ProductContext();
IQueryable<Category> query = db.Categories;
return query;
}
I am a little confused by
IQueryable<Category>
as well as the line
IQueryable<Category> query = db.Categories;
What I think it does is that it is a method called GetCategories() that only accepts Category objects. The method defines a new instance productcontext, it then runs some type of query and returns it. I could be close or way off. I just want to make sure.
... method called GetCategories() that only accepts Category objects ...
IQueryable<Category> is a type just like intor string so the method accepts nothing, it judt returns categories in a queryable way (IQueryable).
The IQueryable return type is used to indicate you want C# to pass along any filters that you use on the GetCategories() method to be passed directly to the database. Even though the method is setup to pass all categories back, you can limit them at a higher level. This saves you from having to create multiple methods for each filter you can think of that goes back to the database.
Here is link to a StackOverflow Example about the differences between IEnumerable and IQueryable
So I think the part you're having trouble with is the generic return type in the method signature, it can be a strange syntax if you haven't come across it before.
Your method is returning a type of IQueryable<Category>, so you're going to be returning an object that implements the interface IQueryable<T>, specifically one which is implemented to work specifically with Category objects.
If you wanted to create a list of strings, you'd do something like:
MyStrings = new List<string>();
And if you wanted to create a method to return a list of strings:
public List<string> FetchMyStrings(); // List<string> is your return type.
In your case, you're returning a list of Category objects:
public List<Category> FetchMyCategories(); // List<Category> is your return type.
For some excellent explanations of IQueryable<T>, and why you'd be interested in it, I'd recommend the answers here:
What is the difference between IQueryable<T> and IEnumerable<T>?
The rest of the code seems to initialise a new database connection, and returns a queryable object, allowing you to get at the categories for use elsewhere in your code.

What is the purpose of AsQueryable()?

Is the purpose of AsQueryable() just so you can pass around an IEnumerable to methods that might expect IQueryable, or is there a useful reason to represent IEnumerable as IQueryable? For example, is it supposed to be for cases like this:
IEnumerable<Order> orders = orderRepo.GetAll();
// I don't want to create another method that works on IEnumerable,
// so I convert it here.
CountOrders(orders.AsQueryable());
public static int CountOrders(IQueryable<Order> ordersQuery)
{
return ordersQuery.Count();
}
Or does it actually make it do something different:
IEnumerable<Order> orders = orderRepo.GetAll();
IQueryable<Order> ordersQuery = orders.AsQueryable();
IEnumerable<Order> filteredOrders = orders.Where(o => o.CustomerId == 3);
IQueryable<Order> filteredOrdersQuery = ordersQuery.Where(o => o.CustomerId == 3);
// Are these executed in a different way?
int result1 = filteredOrders.Count();
int result2 = filteredOrdersQuery.Count();
Do the IQueryable versions of these extension methods just build up an Expression that ends up doing the same thing once its executed? My main question is, whats a real use case for using AsQueryable?
There are a few main uses.
As mentioned in other answers, you can use it to mock a queryable data source using an in-memory data source so that you can more easily test methods that will eventually be used on a non-enumerable based IQueryable.
You can write helper methods for manipulating collections that can apply to either in-memory sequences or external data sources. If you write your help methods to use IQueryable entirely you can just use AsQueryable on all enumerables to use them. This allows you to avoid writing two separate versions of very generalized helper methods.
It allows you to change the compile time type of a queryable to be an IQueryable, rather than some more derived type. In effect; you'd use it on an IQueryable at the same times that you'd use AsEnumerable on an IEnumerable. You might have an object that implements IQueryable but that also has an instance Select method. If that were the case, and you wanted to use the LINQ Select method, you'd need to change the compile time type of the object to IQueryable. You could just cast it, but by having an AsQueryable method you can take advantage of type inference. This is simply more convenient if the generic argument list is complex, and it is actually necessary if any of the generic arguments are anonymous types.
The most valid case I have for AsQueryable is unit testing. Say I have the following somewhat contrived example
public interface IWidgetRepository
{
IQueryable<Widget> Retrieve();
}
public class WidgetController
{
public IWidgetRepository WidgetRepository {get; set;}
public IQueryable<Widget> Get()
{
return WidgetRepository.Retrieve();
}
}
and I want to write a unit test to make sure the controller passes back the results returned from the repository. It'd look something like this:
[TestMethod]
public void VerifyRepositoryOutputIsReturned()
{
var widget1 = new Widget();
var widget2 = new Widget();
var listOfWidgets = new List<Widget>() {widget1, widget2};
var widgetRepository = new Mock<IWidgetRepository>();
widgetRepository.Setup(r => r.Retrieve())
.Returns(listOfWidgets.AsQueryable());
var controller = new WidgetController();
controller.WidgetRepository = widgetRepository.Object;
var results = controller.Get();
Assert.AreEqual(2, results.Count());
Assert.IsTrue(results.Contains(widget1));
Assert.IsTrue(results.Contains(widget2));
}
where really, all the AsQueryable() method allows me to do is satisfy the compiler when setting up a mock.
I'd be interested where this is used in application code though.
As sanjuro noted, the purpose of AsQueryable() is explained in Using AsQueryable With Linq To Objects And Linq To SQL. In particular, the article states,
This offers an excellent benefits in real word scenarios where you have certain methods on an entity that return an IQueryable of T and some methods return List. But then you have business rule filter that needs to be applied on all the collection regardless if the collection is returned as IQueryable of T or IEnumerable of T. From a performance stand point, you really want to leverage executing the business filter on the database if the collection implements IQueryable otherwise fall back to apply the business filter in memory using Linq to object implementation of delegates.
The purpose of AsQueryable() is greatly explained in this article Using AsQueryable With Linq To Objects And Linq To SQL
From Remarks section of MSDN Queryable.AsQueryable Method:
If the type of source implements IQueryable, AsQueryable(IEnumerable) returns it directly. Otherwise, it returns an IQueryable that executes queries by calling the equivalent query operator methods in Enumerable instead of those in Queryable.
Thats is exactly what is mentioned and used in above article.
In your example, it depends on what is orderRepo.GetAll returning, IEnumerable or IQueryable(Linq to Sql). If it returns IQueryable, the Count() method will be executed on database otherwise it will be executed in memory. Look carefully at example in referenced article.
Interface IQueryable quoting documentation:
The IQueryable interface is intended for implementation by query
providers.
So for someone that intends to make its datastracture queryable in .NET, that datastructure that not necessary can be enumerated or have valid enumerator.
IEnumerator is an interface for iterating and processing stream of data instead.

Entity Framework 5 performing full table scan

I have the following code:
public List<anEntity> Get(int page, int pagesize, Func<anEntity, IComparable> orderby)
{
using (var ctx = new MyContext())
{
return ctx.anEntity.OrderBy(orderby).Skip(pagesize * page).Take(pagesize).ToList();
}
}
When I check my database profile (SqlServer 2012) I can see an horrible full table scan without any "TOP" clause.
The interesting part:
If I do something similar but specifying a concrete orderby:
return ctx.anEntity.OrderBy(x => x.aField).Skip(pagesize * page).Take(pagesize).ToList();
The profile shows a beautiful "TOP" clause.
I would like to avoid having lot's of methods, one for each "orderby" possibility. Any hint would be very appreciated.
That's because your orderby parameter is a function rather than expression. There is no way to translate an arbitrary function into SQL, so all your data has to be on the client side before that function is called.
Change the parameter type to Expression<Func<anEntity, T>>, where T is a new generic parameter that you should add to your Get method, and it will work as expected.
Of course, you won't be able to use a custom IComparable, but there is no way around that: custom code cannot be translated into SQL.

Returning IQueryable or Enumerated Object

I was wondering about the performance difference between these two scenarios and what could the disadvantages be over each other?
First scenario :
public class Helper //returns IQueryable
{
public IQueryable<Customer> CurrentCustomer
{
get{return new DataContext().Where(t=>t.CustomerId == 1);
}
}
public class SomeClass
{
public void Main()
{
Console.WriteLine(new Helper().CurrentCustomer.First().Name;
}
}
The second scenario :
public class Helper //returns Enumerated result
{
public Customer CurrentCustomer
{
get{return new DataContext().First(t=>t.CustomerId == 1);
}
}
public class SomeClass
{
public void Main()
{
Console.WriteLine(new Helper().CurrentCustomer.Name;
}
}
Thanks in advance.
Well, the main difference that I can see is when the query is executed and what else you can do with the query.
For example, suppose your Customer object has some large fields. Using the second approach, you will always fetch them. Using the first approach you could write:
string name = helper.CurrentCustomer.Select(x => x.Name).First();
That would then only need to query the single field in the database. In terms of timing, the query will only be executed when you actually request the data (which is how it's able to wait until after you've used Select to work out what to put in the query in the above case). That has pros and cons - it can make it harder to reason about, but it can save some work too. In terms of the "reasoning about" side, you know that once you've got a customer, you've got an object you can just work with. If you use the same queryable twice though, you need to know whether your LINQ query provider is going to cache the result... if you write:
IQueryable<Customer> currentCustomerQuery = helper.CurrentCustomer;
Customer x = currentCustomerQuery.First();
Customer y = currentCustomerQuery.First();
will that issue the query once or twice? I suspect it very much depends on the provider, but I wouldn't like to make any guesses about specific ones.
The other thing to think about is how easy it is to use the API you're building. Personally I'd normally find it easier to use an API which gives me the data I want rather than a query I can fetch that data from. On the other hand, it is slightly less flexible.
One option would be to allow both - have a GetCurrentCustomerQuery() and a GetCurrentCustomer() method. (I probably wouldn't make them properties myself, but that's merely a matter of personal preference.) That way you can get the flexibility you want when you really need it, but have a simple way of just getting the current customer as an object.
In short, using IQueryable is far better and allows you further filter the returned IQueryable down the path, without actually having the object or collection loaded into the memory. In this case, the return type is a simple Customer class and impact would be minimal, but in case of collections, you are strongly advised to use IQueryable. Chris Sells shows the problem in more depth here
The difference between the methods is that the first one returns an expression that can return the object, whlie the second one has already executed the expression and returns the object.
In this exacty scenario the difference isn't very useful, and returning a single object as an expression is not very intuitive.
A scenario where the difference is more useful is if you have a method that returns several objects. The deferred execution of the expression means that you will only load the objects that you actually use. In the case that you only need the first few objects, the rest of the objects will not be created.

Categories