Should I bind navigation properties or entity ids in reusable components?

Caleb Weeks 0 Reputation points
2024-12-05T20:38:11.81+00:00

I am using Blazor with InteractiveServer at the applcation level and Radzen component library.

I would like to create resuable components that fetch their own data for things like dropdowns. For example, I have a Request entity with the following fields:

public class Request
{
    public int Id { get; set; }
    public int RequesterId { get; set; }
    public virtual User Requester { get; set; }
    public virtual ICollection<User>? Alternates { get; set; }
}

I am extending the RadzenDropDown component like so:

public class UserDropDown<TValue> : RadzenDropDown<TValue>
{
    [Inject] public IDbContextFactory<DataContext> DbFactory { get; set; }
    public UserDropDown() : base()
    {
        TextProperty = nameof(User.FullName);
        AllowSelectAll = false;
        AllowClear = false;
    }
    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
        using DataContext dbContext = DbFactory.CreateDbContext();
        Data = await dbContext.Users.ToListAsync();
    }
    protected override async Task OnParametersSetAsync()
    {
        await base.OnParametersSetAsync();
        Chips = Multiple;
    }
}

When using the component, I could either bind to request.Requester or request.RequesterId. For the alternates, there is an advantage to just binding to the navigation property request.Alternates and letting the Radzen component handle adding and removing users from the collection. Then I don't have to worry about diffing a list of ids to figure out what operations to perform on the collection. But the parent component using <UserDropDown /> fetches the request in a different dbContext, and EF Core does not see the users in the alternates list as the same objects.

So, I think my options are:

  1. Override GetHashCode() and Equals() on the Request class so that EF compares them correctly
  2. Fetch the list of Users in the parent component and pass them to the UserDropDown
  3. Work with the ids instead of with the navigation properties

I have tried all three of these approaches and they seem to each have pros and cons. What is the recommended way of accomplishing this?

Thanks!

Entity Framework Core
Entity Framework Core
A lightweight, extensible, open-source, and cross-platform version of the Entity Framework data access technology.
779 questions
Blazor
Blazor
A free and open-source web framework that enables developers to create web apps using C# and HTML being developed by Microsoft.
1,665 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
11,337 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Bruce (SqlWork.com) 72,996 Reputation points
    2024-12-05T22:18:42.9933333+00:00

    why are you storing User entities in the dropdown? seems like a collection of name/value pairs of FullName and Id would be all that's required.

    if the hosting compoent can change the collection, then I'd just have a variable collection the dropdown bound to.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.