I've created a small test class, that returns data from an xml file.
I now want to make it more dynamic using linq but cannot get it to work.
public class LenderCollection
{
string fileName = "C:\\Lenders.xml";
public IEnumerable<Lender> Lenders { get; set; }
public void FetchLenders(Expression<Func<Lender, bool>> predicate = null)
{
IEnumerable<Lender> lenders = XmlHelper.GetObjectFromXml<List<Lender>>(fileName, "AllLenders");
Lenders = predicate.IsNotNull() ? lenders.Where(predicate) : lenders;
}
}
Visual Studio is giving an error on the section "lenders.Where(predicate)" - the message is "... does not contain a definition for Where..."
Any ideas what I'm doing wrong?
* UPDATE *
It seems to be something to do with the predicate - .Where is avaialable otherwise.
There's no extension method Where that extends IEnumerable<T> and takes a parameter of type Expression<Func<T, bool>>.
You have two options:
Use an IQueryable<Lender> instead of IEnumerable<Lender> (you can this easily by just calling .AsQueryable()) if you wan to keep the parameter predicate as Expression<Func<Lender, bool>>
Use the type Func<Lender, bool> instead of Expression<Func<Lender, bool>> for the predicate parameter. Since you're loading your data from a file, there's no point in using an IQueryable over an IEnumerable.
It's complaining that whatever type lenders is does not have a .Where method. This is either because:
You haven't included using System.Linq;
The type of lenders isn't an IEnumerable or similar.
Replace:
lenders.Where(predicate)
With:
lenders.ToList().Where(predicate)
Both should be able to return IEnumerable.
The main downfall with this is that the query will execute on the .ToList() command. I guess this is down to what you expect your function to be doing though, and if this is acceptable for your needs.
Related
I used Dynamic Library in order to generate Lambda Expression that can be executed and return a content based on dynamic query prams,
my problem is with the context filter (using HasQueryFilter statement) that I need to ignore it before execute the query
I tried to use IgnoreQueryFilters, but isn't working with the IQueryable
IQueryable<object> EQueryableItems = (IQueryable<object>)typeof(ApplicationDbContext).GetProperty("Users-Table").GetValue(_appDbContext, null)
IQueryable<object> QueryResult = (IQueryable<object>) EQueryableItems.Where("Id > 1500");
EQueryableItems will contain data based on the context query, I need to get all data not just the result of the filter.
EF Core specific queryable extension methods are available for IQueryable<object>, hence it can be used with the provided code:
IQueryable<object> EQueryableItems = ...;
EQueryableItems = EQueryableItems.IgnoreQueryFilters(); // <-- defined and works
However, if you want to work with non generic IQueryable interface, you can create and use a custom extension method similar to
using System.Linq;
using System.Linq.Expressions;
namespace Microsoft.EntityFrameworkCore
{
public static class CustomQueryableExtensions
{
public static IQueryable IgnoreQueryFilters(this IQueryable source) =>
source.Provider.CreateQuery(Expression.Call(
typeof(EntityFrameworkQueryableExtensions),
nameof(EntityFrameworkQueryableExtensions.IgnoreQueryFilters),
new[] { source.ElementType },
source.Expression));
}
}
which would enable usage of
IQueryable EQueryableItems = ...;
EQueryableItems = EQueryableItems.IgnoreQueryFilters(); // <-- custom defined and works
You can add similar custom extensions methods for other EF Core specific IQueryable<T> extension methods like AsNoTracking(), AsTracking(), AsSplitQuery() etc. if needed, using the same pattern as the above implementation.
I'm trying to build an entity manager in Dart which uses reflection. The idea is that the method getById(String id, String returnClass) calls a method _get[returnClass]ById(String id).
To accomplish this I'm using dart:mirrors and try to determine if my entity manager object has such a method and call it then. Unfortunately the LibraryMirror doesn't contain any functions.
class EntityMgr {
Object getById(String id, String returnClass) {
InstanceMirror result = null;
String methodName = '_get'+returnClass+'ById';
// Check if a method '_get[returnClass]Byid exists and call it with given ID
if(_existsFunction(methodName)) {
Symbol symbol = new Symbol(methodName);
List methodParameters = new List();
methodParameters.add(id);
result = currentMirrorSystem().isolate.rootLibrary.invoke(symbol, methodParameters);
}
return result;
}
Product _getProductById(String id) {
return new Product();
}
bool _existsFunction(String functionName) {
return currentMirrorSystem().isolate.rootLibrary.functions.containsKey(functionName);
}
}
The mirrors library has changed significantly since this response and no longer reflects the api mentioned in this answer
Isolate's are for concurrent programming and you probably don't have any isolates running. Where you want to look is currentMirrorSystem().libraries, or you can use currentMirrorSystem().findLibrary(new Symbol('library_name')).
You need to know the library because a function or class with the same Symbol could me in different libraries but have completely different signatures.
how to invoke class form dart library string or file shows how to get the class mirror from the library and class name.
The ClassMirror contains the methods, the getters and the setters. The methods mirror does not contain the getters or setters.
final Map<Symbol, MethodMirror> methods
final Map<Symbol, MethodMirror> getters
final Map<Symbol, MethodMirror> setters
That being said, you might want to check out the dart serialization at http://api.dartlang.org/docs/bleeding_edge/serialization.html since it might already do exactly what you're trying to do.
Finding the need to be able to get method names in a declarative manner (for AOP, reflection, etc) such that compiler checking enforces breaking changes etc. Good example:
invocation.Method.Name.Equals("GetAll"
.. is there a way to do this like with a lambda/generic method so i don't have to put the method name as a string literal?
I've used things like this before to get property names:
public static string GetPropertyName<T, P>(Expression<Func<T, P>> propSelector)
where T : class
{
return (propSelector.Body as MemberExpression).Member.Name;
}
.. but is there a reliable and easy way to do the same for methods?
You can do something like this with delegates:
public static string MethodName(Delegate d) {
return d.Method.Name;
}
// and to use...
MethodName(new Func<object, int>(Convert.ToInt32));
If there's a particular delegate signature you use, you can create specific overloads:
public static string MethodName(Func<object, int> d) {
return MethodName((Delegate)d);
}
MethodName(Convert.ToInt32);
You might also be able to do something with generics, if you have a play around with it.
Pardon me if this question has already been asked. HttpContext.Current.Session["key"] returns an object and we would have to cast it to that particular Type before we could use it. I was looking at various implementations of typed sessions
http://www.codeproject.com/KB/aspnet/typedsessionstate.aspx
http://weblogs.asp.net/cstewart/archive/2008/01/09/strongly-typed-session-in-asp-net.aspx
http://geekswithblogs.net/dlussier/archive/2007/12/24/117961.aspx
and I felt that we needed to add some more code (correct me if I was wrong) to the SessionManager if we wanted to add a new Type of object into session, either as a method or as a separate wrapper. I thought we could use generics
public static class SessionManager<T> where T:class
{
public void SetSession(string key,object objToStore)
{
HttpContext.Current.Session[key] = objToStore;
}
public T GetSession(string key)
{
return HttpContext.Current.Session[key] as T;
}
}
Is there any inherent advantage in
using
SessionManager<ClassType>.GetSession("sessionString")
than using
HttpContext.Current.Session["sessionString"] as ClassType
I was also thinking it would be nice
to have something like
SessionManager["sessionString"] = objToStoreInSession,
but found that a static class cannot have an indexer. Is there any other way to achieve this ?
My thought was create a SessionObject which would store the Type and the object, then add this object to Session (using a SessionManager), with the key. When retrieving, cast all objects to SessionObject ,get the type (say t) and the Object (say obj) and cast obj as t and return it.
public class SessionObject { public Type type {get;set;} public Object obj{get;set;} }
this would not work as well (as the return signature would be the same, but the return types will be different).
Is there any other elegant way of saving/retrieving objects in session in a more type safe way
For a very clean, maintainable, and slick way of dealing with Session, look at this post. You'll be surprised how simple it can be.
A downside of the technique is that consuming code needs to be aware of what keys to use for storage and retrieval. This can be error prone, as the key needs to be exactly correct, or else you risk storing in the wrong place, or getting a null value back.
I actually use the strong-typed variation, since I know what I need to have in the session, and can thus set up the wrapping class to suit. I've rather have the extra code in the session class, and not have to worry about the key strings anywhere else.
You can simply use a singleton pattern for your session object. That way you can model your entire session from a single composite structure object. This post refers to what I'm talking about and discusses the Session object as a weakly typed object: http://allthingscs.blogspot.com/2011/03/documenting-software-architectural.html
Actually, if you were looking to type objects, place the type at the method level like:
public T GetValue<T>(string sessionKey)
{
}
Class level is more if you have the same object in session, but session can expand to multiple types. I don't know that I would worry about controlling the session; I would just let it do what it's done for a while, and simply provide a means to extract and save information in a more strongly-typed fashion (at least to the consumer).
Yes, indexes wouldn't work; you could create it as an instance instead, and make it static by:
public class SessionManager
{
private static SessionManager _instance = null;
public static SessionManager Create()
{
if (_instance != null)
return _instance;
//Should use a lock when creating the instance
//create object for _instance
return _instance;
}
public object this[string key] { get { .. } }
}
And so this is the static factory implementation, but it also maintains a single point of contact via a static reference to the session manager class internally. Each method in sessionmanager could wrap the existing ASP.NET session, or use your own internal storage.
I posted a solution on the StackOverflow question is it a good idea to create an enum for the key names of session values?
I think it is really slick and contains very little code to make it happen. It needs .NET 4.5 to be the slickest, but is still possible with older versions.
It allows:
int myInt = SessionVars.MyInt;
SessionVars.MyInt = 3;
to work exactly like:
int myInt = (int)Session["MyInt"];
Session["MyInt"] = 3;
I need to log all the function parameters in a dozen functions.
Is there a way to pro grammatically determine all the parameters and their values (or at least their .ToString() value)? Perhaps via reflection?
Here is an example of how to do this with PostSharp
http://consultingblogs.emc.com/merrickchaffer/archive/2009/08/04/using-postsharp-to-log-method-entry-and-exit-in-net-code.aspx
You can also roll your own
http://www.developerfusion.com/article/5307/aspect-oriented-programming-using-net/3/
To the best of my knowledge there's no way to use reflection to dynamically list and determine value of local variables. You can use reflection to get type information about the parameters of a method, but only the declared type - you can't automatically get information about the actual arguments, because the reflection metadata gives information about the method definition, not the specific values passed to it at runtime.
You can, however, do something like this:
static class Extensions
{
public static string GetTypeAndValue(this object obj)
{
return String.Format("{0}: {1}", obj.GetType().Name, obj.ToString());
}
}
Then, from within each method in which you want to perform logging, do something like
private void SomeMethodToBeLogged(string some_string, int some_int, bool some_bool)
{
Logger.Log(String.Format("SomeMethodToBeLogged({0}, {1}, {2})",
some_string.GetTypeAndValue(),
some_int.GetTypeAndValue(),
some_bool.GetTypeAndValue()));
}