0

While somewhat powerful, the System.Linq.Dynamic library has a surprising lack of documentation, especially in regards to what conventions must be followed for more complex queries.

In a query I'm working on, it contains a FirstOrDefault call, but I can't seem to get it to work.

Here's the whole (unworking) expression:

"Locations.FirstOrDefault(x => x.IsPrimaryLocation).Address1 as Address"

Can I write this FirstOrDefault expression to work with Dynamic linq?

What is the correct way to write this expression?

Mark Rogers
  • 96,497
  • 18
  • 85
  • 138
  • Nothing to do with dynamic linq, but `FirstOrDefault()` can return a `null` value which would throw an exception when you try to access `Address1` (or any) property. – DavidG Oct 06 '14 at 14:23
  • True, though my particular problem occurs before it can reach that point, since it can't parse the string correctly. I would accept an answer that solved this with just First(), instead of FirstOrDefault(). – Mark Rogers Oct 06 '14 at 14:26
  • This may help http://stackoverflow.com/questions/4849973/use-of-single-in-dynamic-linq – DavidG Oct 06 '14 at 14:30
  • So I guess, one has to edit the source code of Linq.Dynamic and add the FirstOrDefault method in? – Mark Rogers Oct 06 '14 at 14:33
  • Looks like it. Having not used DL, I really couldn't say. – DavidG Oct 06 '14 at 14:34
  • Is the whole expression dynamic or just the part inside the `FirstOrDefault` ? – Magnus Oct 06 '14 at 20:17
  • The whole expression inside the quotes. – Mark Rogers Oct 06 '14 at 20:37

1 Answers1

1

Extending the dynamic library is certainly an option as already suggested. an alternative given the Where in Dynamic Linq returns an Iqueryable

 public static class DynamicQueryable {

    public static IQueryable<T> Where<T>(this IQueryable<T> source, string predicate, params object[] values) { return (IQueryable<T>) Where((IQueryable) source, predicate, values); }

    public static IQueryable Where(this IQueryable source, string predicate, params object[] values)       {

using a DYnamic Object for the context or repository "locations".
Then use a where which could contain dynamic string predicate and follow with firstOrDefault.
(catch or test for null not considered)

DynamicLocations.Where(x => x.IsPrimaryLocation).FirstOrDefault( ).Address1 as Address;

or dynamic where if needed

DynamicLocations.Where("IsPrimaryLocation",new string[]).FirstOrDefault( ).Address1 as Address;

Details: You can expose on a method on a generic repository Class which you instantiate as a dynamic

     public virtual IQueryable<TPoco> DynamicWhere(string predicate, params object[] values) {
        return AllQ().Where(predicate, values);
    }

Dynamic Generic Repository instantiation Sample

  public class RepositoryFactory<TPoco>  where TPoco : BaseObject,new() {

    public IRepositoryBase<TPoco> GetRepository(DbContext context) {

       // get the Pocotype for generic repository instantiation
        var pocoTypes = new[] {typeof (TPoco)};  // but supports <T,U>
        Type repBaseType = typeof (RepositoryBase<>);

        IRepositoryBase<TPoco> repository = InstantiateRepository(context, repBaseType, pocoTypes);

        return repository;
    }


    private IRepositoryBase<TPoco> InstantiateRepository(DbContext context, Type repType, params Type[] args) {

        Type repGenericType = repType.MakeGenericType(args);
        object repInstance = Activator.CreateInstance(repGenericType, context);
        return (IRepositoryBase<TPoco>)repInstance;
    }

}
phil soady
  • 11,043
  • 5
  • 50
  • 95