Skip to content

feat: Provides a helper class that makes [LinqraftMappingGenerate] easier to use. #249

@arika0093

Description

@arika0093

This is an improvement based on the implementation of #238/#245. Currently, it is defined as follows.

public static partial class SampleClassQuery
{
  [LinqraftMappingGenerate("ProjectToSampleClassDto")]
  internal static IQueryable<SampleClassDto> DummyQuery(this IQueryable<SampleClass> source) => source
    .SelectExpr<SampleClass, SampleClassDto>(x => new
    {
      Id = x.Id,
      CustomerName = x.Customer?.Name,
      // ...
    });


  // generated method will be:
  internal static IQueryable<SampleClassDto> ProjectToSampleClassDto(this IQueryable<SampleClass> source)
    => source.Select(/* ... */);
}

While this has the advantage of allowing multiple definitions in the same class, it is somewhat verbose.
Therefore, we provide a helper class that can be simplified as follows.

// linqraft provided
public abstract class LinqraftMappingDeclare<T>
{
    // user must implement this method to define mapping (dummy)
    protected abstract void DefineMapping();
    // dummy source for use SelectExpr method
    protected IQueryable<T> Source => Enumerable.Empty<T>().AsQueryable();
}

// user write
namespace YourNamespace;

// if user want to control generated method name, they can use attribute in class level
// [LinqraftMappingGenerate("FooToFooDto")]
internal class UseHelperSample : LinqraftMappingDeclare<Foo>
{
    protected override void DefineMapping()
    {
        // write code that uses SelectExpr in method
        Source.SelectExpr<Foo, FooDto>(x => new { x.Id });
    }
}

// then, source generator will generate the following code:

// Generated class is created within the namespace where the original class exists.
namespace YourNamespace
{
    // accessibility is retrieved from user class. in this case, "internal".
    // classname is suffixed with hash to avoid name collision.
    internal static partial class UseHelperSample_HASH1234
    {
        // default generated method name is "ProjectTo" + entity name
        // can be changed by using LinqraftMappingGenerate attribute
        public static IQueryable<FooDto> ProjectToFooDto(this IQueryable<Foo> x)
            // transrated method
            => x.Select(x => new FooDto { Id = x.Id });
    }
}

// user can use like this:
var query = dbContext.Foos.ProjectToFooDto();

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requestgeneratorrelational source-generator

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions