1

I have following Expression Func which is receiving two input paramters, first is Person Object, second is bool and returning another type of Object PersonProfile

private Exression<Func<Person, bool, PersonProfile>> PersonProfileProjection => (person, isValid) =>
        new PersonProfile
        {
             FirstName = person.FirstName,
             HasAddress = isValid ? person.Address1 : null
        };

And I am trying to call this while fetching Person table from dbContext.

_dbContext.Persons.Select(PersonProfileProjection); 

I am confused how to send boolean parameter inside PersonProfileProjection. It works when I only put one input and one output parameter like this. But I want extra boolean input as well.

Any help would be highly appreciated.

Saya
  • 63
  • 9

2 Answers2

0

You can follow Microsoft documentation for this : Expression Class

One sample created for SQLite that show above function usage.

public void GetData()
    {
        var connection = new SQLiteConnection(@"Data Source=database.sqlite;Version=3;");
        var context = new DataContext(connection);

        connection.Open();

        var createtableQuery = @"
                                drop table Company;
                                CREATE TABLE[Company]
                                (
                                    [ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
                                    [Seats] INTEGER NOT NULL
                                );
                                ";

        var command = new SQLiteCommand(createtableQuery, connection);
        command.ExecuteNonQuery();
        Company com = new Company()
        {
            Id = 6,
            Seats = 7
        };

        context.GetTable<Company>().InsertOnSubmit(com);
        context.SubmitChanges();

        var companies = context.GetTable<Company>();

        foreach (var company in companies)
        {
            Console.WriteLine("Company: {0} {1}",
                company.Id, company.Seats);
        }

        //compile Expression using Compile method to invoke it as Delegate
        Func<int,int, Company> PersonProfileProjectionComp = PersonProfileProjection.Compile();

        var dd = companies.Select(p => PersonProfileProjectionComp(p.Id,p.Seats));

      //// Below line inline use. Both works.
      //var dd = companies.Select(p => PersonProfileProjection.Compile().Invoke(p.Id,p.Seats));
    }

    private System.Linq.Expressions.Expression<Func<int, int, Company>> PersonProfileProjection => (person, seats) =>
    new Company
    {
        Id = person,
        Seats = seats
    };

or in one line use this : PersonProfileProjection.Compile().Invoke(person, isValid)

Jophy job
  • 1,924
  • 2
  • 20
  • 38
  • When using IQueryables, as expected, because the question is about EF and Expressions, the invoke leads to exception: The LINQ expression node type 'Invoke' is not supported in LINQ to Entities.' – Harald Coppoolse Oct 17 '18 at 13:14
  • Hi @HaraldCoppoolse i not checked for EF, but i put both options in answer , //compile Expression using Compile method to invoke it as Delegate Func PersonProfileProjectionComp = PersonProfileProjection.Compile(); var dd = companies.Select(p => PersonProfileProjectionComp(p.Id,p.Seats)); //// Below line inline use. Both works. //var dd = companies.Select(p => PersonProfileProjection.Compile().Invoke(p.Id,p.Seats)); – Jophy job Oct 22 '18 at 17:29
0

You could declare it as a Func instead of an expression:

private Func<Person, bool, PersonProfile> PersonProfileProjection => (person, isValid) =>
        new PersonProfile
        {
            FirstName = person.FirstName,
            HasAddress = isValid // do what you meant to do
        };

... and call it as:

_dbContext.Persons.Select(p => PersonProfileProjection(p, true)); 

You could as well write an ordinary method:

private PersonProfile PersonProfileProjection(Person person, bool isValid)
{
    return new PersonProfile
    {
        FirstName = person.FirstName,
        HasAddress = isValid // do what you want to do
    };
}

...and call it the same way:

_dbContext.Persons.Select(p => PersonProfileProjection(p, true)); 
kaffekopp
  • 2,551
  • 6
  • 13
  • 2
    Alas, this will only work as Enumerable, not as Queryable: if you want your database management system to execute the query, the IQueryable.Provider must translated the expression into SQL, and SQL doesn't know the concept of PersonProfileProjection – Harald Coppoolse Oct 17 '18 at 08:21