EntityFrameworkCore.Projectables icon indicating copy to clipboard operation
EntityFrameworkCore.Projectables copied to clipboard

I am want to Use your nuget in runtime for generation class using IL

Open P9avel opened this issue 2 years ago • 8 comments

Hi. I am want to generate class like this in rntime using Emit

public class User { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; }

[Projectable]
public string FullName => FirstName + " " + LastName;

}

In result extension methods not generated. How to use your nuget in my case?

P9avel avatar Apr 26 '23 08:04 P9avel

You can't. The whole point of this library is to write companion expressions at compile time using roslyn source generators.

koenbeuk avatar Apr 26 '23 13:04 koenbeuk

Possible exists way ?

P9avel avatar Apr 26 '23 17:04 P9avel

Possible can you to extend ProjectableAttriibute for mmy case? I am want follow

public class User
{
   public int Id { get; set; }
   public string FirstName { get; set; }
   public string LastName { get; set; }

   [Projectable<MyUserExtensions>(nameof(MyUserExtensions.MyFullNameImpl))]
   public string FullName => FirstName + " " + LastName;
}

public static class MyUserExtensions {
    
    public static Expression<string> MyFullNameImpl(this User user) => 
        user.FirstName +" "+ user.LastName;
}

In this case

  1. In compile-time you not generate UserExtensions class for User.FullName property
  2. In runtime you will use MyUserExtensions.MyFullNameImpl method for User.FullName query

I.e. i am want to wrote all Extensions methods in common class. And when generate IL User class, i am want to generate ProjectableAttribute and using my common class. I really need this functionality.

P9avel avatar Apr 26 '23 19:04 P9avel

This is currently already supported for members within the same type, e.g. this is allowed:

public record Entity
{
    public int Id { get; set; }
            
    [Projectable(UseMemberBody = nameof(Computed2))]
    public int Computed1 => Id;

    private int Computed2 => Id * 2;

    [Projectable(UseMemberBody = nameof(Computed4))]
    public int Computed3 => Id;

    private static Expression<Func<Entity, int>> Computed4 => x => x.Id * 3;
}

Is that sufficient for your use-case?

koenbeuk avatar Apr 27 '23 14:04 koenbeuk

Hi, thank you for your solution. But i need to pass value to Expression function. I.e. am want to have base class with expression and set params in child class. For example

` //Base class created in compile-time/design-time VS public record Base { public int Id { get; set; }

    // Use for LINQ quering from DB
    protected static Expression<Func<Base, int, int>> ComputedBase => (x, multiply) => x.Id * multiply;

    // Use for memory object calculation
    protected int ComputedBaseFunc(int multiply) => Id * multiply;
}

//Generated class in RunTime using IL
public record Entity: Base 
{
    // here 123 pass to 'multiply' param
    [Projectable(UseMemberBody = nameof(ComputedBase), 123)]
    public int Computed1 => ComputedBaseFunc(123);

    // here 777 pass to 'multiply' param
    [Projectable(UseMemberBody = nameof(ComputedBase), 777)]
    public int Computed2 => ComputedBaseFunc(777);
}

`

can you to help in implementation my scenario?

P9avel avatar Apr 28 '23 20:04 P9avel

Hi, can you to help in implementation my scenario?

P9avel avatar May 11 '23 09:05 P9avel

Do you have news about this?

P9avel avatar Jun 27 '23 10:06 P9avel

If I understand you correctly, you're asking for a dynamic expression body replacement strategy where the actual expression body of a projectable method can be configured at runtime.

I think this is a very niche use-case and I'm not planning on implementing it. I'm not against the feature in general and happy to accept a PR if anyone wants to pick it up. I can give some guidelines on how to get started if anyone wants to give this is a shot

koenbeuk avatar Jun 27 '23 23:06 koenbeuk