blazordevita / BlazorDevIta.ERP

Il codice sorgente del progetto realizzato durante le dirette Twitch della community
MIT License
38 stars 14 forks source link

Le entità in relazione non vengono incluse nell'EFRepository #35

Open pietroserrano opened 2 years ago

pietroserrano commented 2 years ago

Ho provato a riutilizzare il componente EFRepository ed ho notato che se utilizzando su una entity in relazione con 1 o più entity, queste non vengono incluse (di solito nei repository che creavo singolarmente per ogni entità dovevo utilizzare il metodo Include o ThenInclude). Per sopperire a ciò ho effettuato una modifica all'EFRepository dove, per effettuare l'inclusione in maniera dinamica. Per fare ciò ho dovuto aggiungere un Attribuite chiamato "IncludeAttribute" e nel momento del recupero delle entità effettuo la "Include" delle sole proprietà che posseggono l'attributo "Include". Ci sono altre strade oppure ho utilizzato in maniera errata l'EFRepository?

pietroserrano commented 2 years ago

Queste sono le modifiche effettuate in EFRepository.cs:

....
public IQueryable<TEntity> GetAll()
{
        var propertyToInclude = typeof(TEntity).GetProperties().Where(
    p => p.CustomAttributes.Any(ca => ca.AttributeType.Name == "IncludeAttribute"));
    foreach(var p in propertyToInclude)
        {
        _set.Include(p.Name);
         }
    return _set;
}

public async Task<TEntity?> GetByIdAsync(TKey id)
{
    var entity = await _set.FindAsync(id);

    if (entity == null)
    {
        return null;
    }

    var propertyToInclude = typeof(TEntity).GetProperties().Where(
        p => p.CustomAttributes.Any(ca => ca.AttributeType.Name == "IncludeAttribute")).Select(x=> x.Name).ToList();

    foreach (var p in _dbContext.Entry(entity).References.Where(p=> propertyToInclude.Contains(p.Metadata.Name)))
    {
        p.Load();
    }

    _dbContext.Entry(entity).State = EntityState.Detached;
    return entity;
}
....

Questo è IncludeAttribute.cs:

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
public class IncludeAttribute : Attribute
{
}

Di seguito un esempio di utilizzo:

public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }

    [Include]
    public Grade Grade { get; set; }
}

public class Grade
{
    public int GradeId { get; set; }
    public string GradeName { get; set; }
    public string Section { get; set; }
}