update generic entity in linq to object - c#

I have a function written in linq to sql
public static bool update(System.Linq.Expressions.Expression<Func<T,bool>> predicate,Action<T> setter)
{
try
{
Context myContext = new Context ();
T updateObject;
updateObject = myContext.GetTable<T>().Where(predicate).First();
setter(updateObject);
nhagoDb.SubmitChanges();
return true;
}
catch (Exception ex)
{
return false;
}
}
but i dont know how to write this in linq to object, especially there's no method like GetTable<T>().Where(predicate).First();
please help
many thanks :)

I don't see that such a method is even necessary in LINQ to objects. Your code can simply do the work itself. E.g.
var myObject = myList.First(x => x.Something);
myObject.UpdateSomething(newValue);
// or just:
myList.First(x => x.Something).UpdateSomething(newValue);
If you did want a method to do this, it would be called like:
myList.Update(x => x.Something, x => x.UpdateSomething(newValue));
The former is shorter, clearer (IMO), and faster than the latter.

You can implement myContext.GetTable() yourself. Create an extension method for Context class.
Inside the method use reflection to find the db set whith type T and return it, the rest of your code will work

Related

Using extension method in Linq to Entities

Code:
public static IEnumerable<TableRowModel> GetRows()
{
var to_ret = db.TableRows.select(x=> new TableRowModel(){
TableRowId = x.TableRowId,
Type = x.Type,
Name = x.Name,
CreatedAt = x.CreatedAt,
ModifiedAt = x.ModifiedAt,
Enums = x.Enums.Select(y => y.ToEnumModel()),
});
return to_ret;
}
public static EnumModel ToEnumModel(this Enum x)
{
var to_ret = new EnumModel()
{
CFPId = x.CFPId,
CreatedAt = x.CreatedAt,
ModifiedAt = x.ModifiedAt,
};
return to_ret;
}
I get the following error when using the GetRows method:
LINQ to Entities does not recognize the method
Given the error, it's understood that LINQ To Entities is not able to recognize the extension method ToEnumModel.
I would like to know if there is a way around this?
So that I would not be repeating ToEnumModel code again in GetRows extension.
Under normal circumstances, when performing an operation like a Where in EntityFramework, it isn't actually executed in memory like when you operate on an enumerable (like a List). Instead, it converted into SQL which is then executed by the Db provider. This means that doing certain things, such as using extension methods on objects, is not an option, as the converter cannot turn such things into SQL.
The quickest and easiest solution would be to load your set in-memory, where it can be operated on like any other enumerable. You can do this like so:
var result = myDbSet.AsEnumerable().Etc()
Etc() here represents all other operations you want to run. Be advised however, that this will load all data into memory, which may be prohibitively slow and expensive in some scenarios. One way to alleviate this is to put AsEnumerable() right before you need to use the extension method, thus offloading as many operations as possible to the provider. For example this:
var result = myDbSet.Where([condition]).AsEnumerable().Select(item => item.ExtensionMethod());
Might be much quicker and lighter than this:
var result = myDbSet.AsEnumerable().Where([condition]).Select(item => item.ExtensionMethod());
Your ability to use extension methods in EF is limited, but you can still extend your IQueryables
public static class Extensions
{
public static IQueryable<MyModelVM> SelectVMs(this IQueryable<MyModel> models)
{
return models.Select(x => new MyModelVM { MyModelId = x.MyModelId });
}
}

Filter "base query" for slightly different results

I am trying to query a database using Entity Framework and I need to make several slightly different queries on the same set of tables. There are a load of navigation properties I need to add and it seems logical to me that I should be able to define the "base query" (i.e the one with all the navigation properties" and then further filter this as required and execute the query.
Some code may help explain further. This is what I am calling my "base query"
private static IEnumerable<HelpdeskTicket> GetAll()
{
IEnumerable<HelpdeskTicket> Tickets;
using (ItManagement_Entities db = new ItManagement_Entities())
{
Tickets = db.HelpdeskTickets.Include("CreatedByPerson")
.Include("HelpdeskCategory")
.Include("HelpdeskPriority")
.Include("HelpdeskStatus");
}
return Tickets;
}
As an example, some of the queries I need to perform are open tickets, recently closed tickets, my tickets, yada yada yada.
My thinking is to have methods similar to the following to do the filtering bit I need without having to define all the .Include()'s again.
public static List<HelpdeskTicketModel> GetAllTickets()
{
List<HelpdeskTicketModel> Tickets = new List<HelpdeskTicketModel>();
GetAll().OrderByDescending(t => t.TicketId)
.ToList()
.ForEach(t => Tickets.Add(HelpdeskTicketModel.Map(t)));
return Tickets;
}
public static List<HelpdeskTicketModel> GetRecentlyClosedTickets()
{
List<HelpdeskTicketModel> Tickets = new List<HelpdeskTicketModel>();
GetAll().Where(t => t.HelpdeskStatus.IsClosedStatus)
.OrderByDescending(t => t.ClosedTime)
.ToList()
.ForEach(t => Tickets.Add(HelpdeskTicketModel.Map(t)));
return Tickets;
}
//And so on...
When I try this I get a System.InvalidOperationException exception thrown complaining that The operation cannot be completed because the DbContext has been disposed, which makes sense really because my query was in a different context, in the GetAll method.
Question is, how do I go about doing what I want?
You may try something similar to the Template Method pattern, where each particular method calls some base, private methods that do the common work and then each one adds its particular bits of the query. Something like that may come handy as a starting point:
// Here you define common parts applicable to all methods, or at least shared among some of them
private static IQueryable<HelpdeskTicket> BuildBaseQuery(this IQueryable<HelpdeskTicket> query)
{
return query.Include("CreatedByPerson")
.Include("HelpdeskCategory")
.Include("HelpdeskPriority")
.Include("HelpdeskStatus");
}
// Here are the particular methods, they create a query, call helper methods for the common bits and add their specifics
public static List<HelpdeskTicketModel> GetAllTickets()
{
List<HelpdeskTicketModel> Tickets = new List<HelpdeskTicketModel>();
using (ItManagement_Entities db = new ItManagement_Entities())
{
Tickets = db.HelpdeskTickets.BuildBaseQuery()
.OrderByDescending(t => t.TicketId)
.ToList()
.ForEach(t => Tickets.Add(HelpdeskTicketModel.Map(t)));
}
return Tickets;
}

Creating an object via lambda factory vs direct "new Type()" syntax

For example, consider a utility class SerializableList:
public class SerializableList : List<ISerializable>
{
public T Add<T>(T item) where T : ISerializable
{
base.Add(item);
return item;
}
public T Add<T>(Func<T> factory) where T : ISerializable
{
var item = factory();
base.Add(item);
return item;
}
}
Usually I'd use it like this:
var serializableList = new SerializableList();
var item1 = serializableList.Add(new Class1());
var item2 = serializableList.Add(new Class2());
I could also have used it via factoring, like this:
var serializableList = new SerializableList();
var item1 = serializableList.Add(() => new Class1());
var item2 = serializableList.Add(() => new Class2());
The second approach appears to be a preferred usage pattern, as I've been lately noticing on SO. Is it really so (and why, if yes) or is it just a matter of taste?
Given your example, the factory method is silly. Unless the callee requires the ability to control the point of instantiation, instantiate multiple instances, or lazy evaluation, it's just useless overhead.
The compiler will not be able to optimize out delegate creation.
To reference the examples of using the factory syntax that you gave in comments on the question. Both examples are trying (albeit poorly) to provide guaranteed cleanup of the instances.
If you consider a using statement:
using (var x = new Something()) { }
The naive implementation would be:
var x = new Something();
try
{
}
finally
{
if ((x != null) && (x is IDisposable))
((IDisposable)x).Dispose();
}
The problem with this code is that it is possible for an exception to occur after the assignment of x, but before the try block is entered. If this happens, x will not be properly disposed, because the finally block will not execute. To deal with this, the code for a using statement will actually be something more like:
Something x = null;
try
{
x = new Something();
}
finally
{
if ((x != null) && (x is IDisposable))
((IDisposable)x).Dispose();
}
Both of the examples that you reference using factory parameters are attempting to deal with this same issue. Passing a factory allows for the instance to be instantiated within the guarded block. Passing the instance directly allows for the possibility of something to go wrong along the way and not have Dispose() called.
In those cases, passing the factory parameter makes sense.
Caching
In the example you have provided it does not make sense as others have pointed out. Instead I will give you another example,
public class MyClass{
public MyClass(string file){
// load a huge file
// do lots of computing...
// then store results...
}
}
private ConcurrentDictionary<string,MyClass> Cache = new ....
public MyClass GetCachedItem(string key){
return Cache.GetOrAdd(key, k => new MyClass(key));
}
In above example, let's say we are loading a big file and we are calculating something and we are interested in end result of that calculation. To speedup my access, when I try to load files through Cache, Cache will return me cached entry if it has it, only when cache does not find the item, it will call the Factory method, and create new instance of MyClass.
So you are reading files many times, but you are only creating instance of class that holds data just once. This pattern is only useful for caching purpose.
But if you are not caching, and every iteration requires to call new operator, then it makes no sense to use factory pattern at all.
Alternate Error Object or Error Logging
For some reason, if creation fails, List can create an error object, for example,
T defaultObject = ....
public T Add<T>(Func<T> factory) where T : ISerializable
{
T item;
try{
item = factory();
}catch(ex){
Log(ex);
item = defaultObject;
}
base.Add(item);
return item;
}
In this example, you can monitor factory if it generates an exception while creating new object, and when that happens, you Log the error, and return something else and keep some default value in list. I don't know what will be practical use of this, but Error Logging sounds better candidate here.
No, there's no general preference of passing the factory instead of the value. However, in very particular situations, you will prefer to pass the factory method instead of the value.
Think about it:
What's the difference between passing the parameter as a value, or
passing it as a factory method (e.g. using Func<T>)?
Answer is simple: order of execution.
In the first case, you need to pass the value, so you must obtain it before calling the target method.
In the second case, you can postpone the value creation/calculation/obtaining till it's needed by the target method.
Why would you want to postpone the value creation/calculation/obtaining? obvious things come to mind:
Processor-intensive or memory-intensive creation of the value, that you want to happen only in case the value is really needed (on-demand). This is Lazy loading then.
If the value creation depends on parameters that are accessible by the target method but not from outside of it. So, you would pass Func<T, T> instead of Func<T>.
The question compares methods with different purposes. The second one should be named CreateAndAdd<T>(Func<T> factory).
So depending what functionality is required, should be used one or another method.

Anonymous type scoping issue

What is the proper way to create a variable that will house a list of anonymous objects that are generated through a LINQ query while keeping the variable declaration outside of a try/catch and the assignment being handled inside of a try/catch?
At the moment I'm declaring the variable as IEnumberable<object>, but this causes some issues down the road when I'm trying to use it later...
i.e.
var variableDeclaration;
try{
...
assignment
...
}catch...
EDIT:
If it's relevant (don't think it is) the list of objects is being returned as a Json result from an MVC3 action. I'm trying to reduce the time that some using statements are open with the DB as I'm having some performance issues that I'm trying to clear up a bit. In doing some of my testing I came across this issue and can't seem to find info on it.
EDIT 2:
If I could request the avoidance of focusing on LINQ. While LINQ is used the question is more specific to the scoping issues associated with Anonymous objects. Not the fact that LINQ is used (in this case) to generate them.
Also, a couple of answers have mentioned the use of dynamic while this will compile it doesn't allow for the usages that I'm needing later on the method. If what I'm wanting to do isn't possible then at the moment the answer appears to be to create a new class with the definition that I'm needing and to use that.
It's possible to get around this by creating a generic Cast method as outlined by Jon Skeet here. It will work and give you the intellisense you want. But, at this point, what's wrong with creating a custom type for your linq method?
public class MyClass
{
public int MyInt { get; set; }
}
IEnumerable<MyClass> myClass =
//Some Linq query that returns a collection of MyClass
Well, if you're using LINQ, the query is not evaluated unless materialized...
So, you might be able to:
var myQuery = //blah
try
{
myQuery = myQuery.ToList(); //or other materializing call
}
catch
{
}
Could you perhaps get away with using dynamic ??
dynamic variableDeclaration;
try
{
variableDeclaration = SomeList.Where(This => This == That);
}
catch { }
Not sure what this will affect further in your code block, but just a thought :)
If you are declaring the variable ahead of using it like a try/catch you can't use [var] as it is intendend. Instead you have to type the the variable.
var x = 0;
try{
x = SomethingReturningAnInt();
}
or
int x;
try{
x = SomethingReturningAnInt();
}
However in your case you don't really "know" what the method returns
var x = ...;
try{
x = Something();
}
catch{}
won't work
Option you have when you don't know the type in advance is use of dynamic:
dynamic x;
try{
x = Something();
}
catch{}
(But that feels like going back to VB4)
Another cheat: you can define variable locally (similarly to Jon's hack in Dave Zych answer) and than use it inside try/catch. As long as you can create the same anonymous item type before try-catch you are OK (as anonymous types wit the same field names and types are considered the same):
var myAnonymouslyType = Enumerable.Repeat(
new {Field1 = (int)1, Field2 = (string)"fake"}, 0);
try
{
myAnonymouslyType = ...(item =>
new {Field1 = item.Id, Field2=item.Text})...
}
...
This is safer option than covered in Jon's casting of anonymous types between functions because compiler will immediately find errors if types don't match.
Note: I'd vote for non-anonymous type if you have to go this way...
Note 2: depending on your actual need consider simply returning data from inside try/catch and having second return of default information outside.
This has vexed me for a while. In the end I've build some Generic helper methods where I can pass in the code that generates the anonymous objects, and the catch code as lamdas as follows
public static class TryCatch
{
public static T Expression<T>(Func<T> lamda, Action<Exception> onException)
{
try
{
return lamda();
}
catch(Exception e)
{
onException(e);
return default(T);
}
}
}
//and example
Exception throwexception = null;
var results = TryCatch.Expression(
//TRY
() =>
{
//simulate exception happening sometimes.
if (new Random().Next(3) == 2)
{
throw new Exception("test this");
}
//return an anonymous object
return new { a = 1, b = 2 };
} ,
//CATCH
(e) => { throwexception = e;
//retrow if you wish
//throw e;
}
);
https://gist.github.com/klumsy/6287279

c# lambda expression - add delegate results to generic list

Question: I have just wrote my first code using c# lambda expressions. It works, but I am not sure if this is the best way to do it. Any recommendations on a better way to do the lambda expression? It seems odd to have numerous lines of code in the expression like I do below.
Background: I have a generic list of delegates. Each delegate function returns an enum value indicating what happened in the function. Upon evaluation of the delegate, I need to add the enum to a List if it was not a specific enum value.
Disclaimer: Code here is very generic, the real code actually does stuff in the delegates to determine the return value!
class Class1
{
public enum WhatHappened
{
ThingA,
ThingB,
Nothing
}
private delegate WhatHappened del();
public static List<WhatHappened> DoStuff()
{
List<del> CheckValues = new List<del>();
List<WhatHappened> returnValue = new List<WhatHappened> { };
CheckValues.Add(delegate { return method1(); });
CheckValues.Add(delegate { return method2(); });
CheckValues.ForEach(x =>
{
WhatHappened wh = x();
if (wh != WhatHappened.Nothing)
returnValue.Add(wh);
});
return returnValue;
}
private static WhatHappened method1()
{
return WhatHappened.Nothing;
}
private static WhatHappened method2()
{
return WhatHappened.ThingA;
}
}
Note: I originally had the lambda like adding all the items (see below), then removing the ones I didn't want (WhatHappened.Nothing).
CheckValues.ForEach(x => returnValue.Add(x()));
Okay, a few suggestions:
Don't call your delegate del. In this case, I'd use Func<WhatHappened> - but if you do want to declare your own delegate type, give it a more descriptive name, and obey the .NET naming conventions.
Instead of using anonymous methods to add to CheckValues, you can just use:
CheckValues.Add(method1);
CheckValues.Add(method2);
The compiler will convert the method groups into delegates.
I'd recommend not using Pascal case for a local variable name to start with.
Your collection initializer for returnValues isn't really doing anything for you - just call the List<T> constructor as normal, or use my code below which doesn't require a local variable to start with.
If your list really only has two delegates in it, I'd just call them separately. It's a lot simpler.
Otherwise you can indeed use LINQ as Jared suggests, but I'd do it slightly differently:
return CheckValues.Select(x => x())
.Where(wh => wh != WhatHappened.Nothing)
.ToList();
EDIT: As suggested, here's the full example. It's not quite the same as Denis's though... I've made a couple of changes :)
public static List<WhatHappened> DoStuff()
{
var functions = new List<Func<WhatHappened>> { Method1, Method2 };
return functions.Select(function => function())
.Where(result => result != WhatHappened.Nothing)
.ToList();
}
(I'm assuming that method1 and method2 have been renamed to fit the naming convention. Of course in real life I'm sure they'd have more useful names anyway...)
I would simply use Linq, but that's just me:
public static List<WhatHappened> DoStuff()
{
List<del> CheckValues = new List<del>();
List<WhatHappened> returnValue = new List<WhatHappened>();
CheckValues.Add(method1);
CheckValues.Add(method2);
return CheckValues
.Select(dlg => dlg())
.Where( res => res != WhatHappened.Nothing)
.ToList();
}
Note that you can also use Func instead of declaring a Delegate type if you want, but that's less terse in that case.
Also, I'd return an IEnumerable<WhatHappened> instead of a List, but it's all about the context.
You can go lambda all the way by chaining Select (map) and Where (filter) instead of multiple FOR loops and IF statements
// get results from the list of functions
var results = CheckValues.Select(x => x());
// filter out only the relevant ones.
var returnValues = results.Where(x => x != WhatHappened.Nothing);
Basically, you should think more declaratively instead of imperatively when work ing with lambdas. It'll help you write more elegant code.
It's a bit more idiomatic to write the following instead of using the delegate keyword. It doesn't change the underlying functionality though.
CheckValues.Add( () => method1() );
Also, I find it more readable to rewrite the ForEach as the following
CheckValues = CheckValues.
Select(x => x()).
Where(wh => wh != WhatHappened.Nothing ).
ToList();
In my opinion, based on the example, it looks fine. You could refactor even more by replacing:
CheckValues.Add(delegate { return method1(); });
CheckValues.Add(delegate { return method2(); });
with:
CheckValues.Add(() => WhatHappened.Nothing);
CheckValues.Add(() => WhatHappened.ThingA);
Here's a LINQ-free solution:
return CheckValues
.ConvertAll<WhatHappened>(x => x())
.FindAll(y => y != WhatHappened.Nothing);
caveat
This is not the most performant solution, as it would iterate twice.
I can't fathom the purpose of the code.. however here goes.
Used delegate chaining
Update: and picked up some Enumerable goodness from Jon n Jared's posts
private delegate WhatHappened WhatHappenedDelegate();
public static List<WhatHappened> DoStuff()
{
WhatHappenedDelegate delegateChain = null;
delegateChain += method1;
delegateChain += method2;
return delegateChain.GetInvocationList()
.Select(x => (WhatHappened) x.DynamicInvoke())
.Where( wh => (wh != WhatHappened.Nothing))
.ToList<WhatHappened>();
}

Categories

Resources