It’s common to want to connect to a database when building microservices and REST APIs using ASP.NET Core and Entity Framework Core. It’s also common to have relationships between database entities. One of the most common relationships is one-to-many. This relationship describes having 1 entity with multiple associated entities. In this tutorial, we’ll go over building Entity Framework Core One-to-Many Relationships using a User model and Blog Posts model as the related entities. Also please take the time to check out the video tutorials as well to get examples of full applications built using ASP.NET Core and SPAs like React and Angular.

Entity Framework One-To-Many Model Relationships

One of the first things that we’re going to do is create our Post model. This represents the number of posts that our user will own. We will reference the User Model as the Author property in the model.

<span class="token keyword">using</span> System<span class="token punctuation">;</span>
<span class="token keyword">using</span> System<span class="token punctuation">.</span>Collections<span class="token punctuation">.</span>Generic<span class="token punctuation">;</span>
<span class="token keyword">using</span> System<span class="token punctuation">.</span>Linq<span class="token punctuation">;</span>
<span class="token keyword">using</span> System<span class="token punctuation">.</span>Threading<span class="token punctuation">.</span>Tasks<span class="token punctuation">;</span>

<span class="token keyword">namespace</span> ASPCoreRelationships<span class="token punctuation">.</span>Models
<span class="token punctuation">{</span>
    <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Post</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">public</span> <span class="token keyword">int</span> PostId <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
        <span class="token keyword">public</span> <span class="token keyword">string</span> Title <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
        <span class="token keyword">public</span> <span class="token keyword">string</span> Content <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
        <span class="token keyword">public</span> ApplicationUser Author <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
        <span class="token keyword">public</span> List<span class="token operator">&lt;</span>PostCategory<span class="token operator">&gt;</span> PostCategories <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

In our User model, we’ll create a property that represents the collection of Posts that the user owns.

<span class="token keyword">using</span> Microsoft<span class="token punctuation">.</span>AspNetCore<span class="token punctuation">.</span>Identity<span class="token punctuation">;</span>
<span class="token keyword">using</span> System<span class="token punctuation">;</span>
<span class="token keyword">using</span> System<span class="token punctuation">.</span>Collections<span class="token punctuation">.</span>Generic<span class="token punctuation">;</span>
<span class="token keyword">using</span> System<span class="token punctuation">.</span>Linq<span class="token punctuation">;</span>
<span class="token keyword">using</span> System<span class="token punctuation">.</span>Threading<span class="token punctuation">.</span>Tasks<span class="token punctuation">;</span>

<span class="token keyword">namespace</span> ASPCoreRelationships<span class="token punctuation">.</span>Models
<span class="token punctuation">{</span>
    <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">ApplicationUser</span> <span class="token punctuation">:</span> IdentityUser
    <span class="token punctuation">{</span>
        <span class="token keyword">public</span> <span class="token keyword">string</span> FirstName <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
        <span class="token keyword">public</span> <span class="token keyword">string</span> LastName <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
        <span class="token keyword">public</span> Address Address <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
        <span class="token keyword">public</span> ICollection<span class="token operator">&lt;</span>Post<span class="token operator">&gt;</span> Posts <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>

    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

Creating the EF Core One-Many-Relationship

When trying to associate the Author and the Post, this can be done one of two ways. Getting the Author and adding Post entity to its collection or posts or getting the Post adding the user to its author property. Here are both examples.

        <span class="token punctuation">[</span>Authorize<span class="token punctuation">]</span>
        <span class="token punctuation">[</span>HttpPost<span class="token punctuation">]</span>
        <span class="token keyword">public</span> <span class="token keyword">async</span> Task<span class="token operator">&lt;</span>ActionResult<span class="token operator">&lt;</span>Post<span class="token operator">&gt;</span><span class="token operator">&gt;</span> <span class="token function">PostPost</span><span class="token punctuation">(</span>Post post<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            <span class="token keyword">var</span> user <span class="token operator">=</span> <span class="token keyword">await</span> _userManager<span class="token punctuation">.</span><span class="token function">FindByIdAsync</span><span class="token punctuation">(</span>User<span class="token punctuation">.</span><span class="token function">FindFirstValue</span><span class="token punctuation">(</span>ClaimTypes<span class="token punctuation">.</span>NameIdentifier<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            post<span class="token punctuation">.</span>Author <span class="token operator">=</span> user<span class="token punctuation">;</span>
            _context<span class="token punctuation">.</span>Posts<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>post<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">await</span> _context<span class="token punctuation">.</span><span class="token function">SaveChangesAsync</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

            <span class="token keyword">return</span> <span class="token function">CreatedAtAction</span><span class="token punctuation">(</span><span class="token string">"GetPost"</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token punctuation">{</span> id <span class="token operator">=</span> post<span class="token punctuation">.</span>PostId <span class="token punctuation">}</span><span class="token punctuation">,</span> post<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
<span class="token punctuation">[</span>Authorize<span class="token punctuation">]</span>
        <span class="token punctuation">[</span>HttpPost<span class="token punctuation">]</span>
        <span class="token keyword">public</span> <span class="token keyword">async</span> Task<span class="token operator">&lt;</span>ActionResult<span class="token operator">&lt;</span>Post<span class="token operator">&gt;</span><span class="token operator">&gt;</span> <span class="token function">PostPost</span><span class="token punctuation">(</span>Post post<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            <span class="token keyword">var</span> user <span class="token operator">=</span> <span class="token keyword">await</span> _userManager<span class="token punctuation">.</span><span class="token function">FindByIdAsync</span><span class="token punctuation">(</span>User<span class="token punctuation">.</span><span class="token function">FindFirstValue</span><span class="token punctuation">(</span>ClaimTypes<span class="token punctuation">.</span>NameIdentifier<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            user<span class="token punctuation">.</span>Posts<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>post<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">await</span> _userManager<span class="token punctuation">.</span><span class="token function">UpdateAsync</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">await</span> _context<span class="token punctuation">.</span><span class="token function">SaveChangesAsync</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">return</span> <span class="token function">CreatedAtAction</span><span class="token punctuation">(</span><span class="token string">"GetPost"</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token punctuation">{</span> id <span class="token operator">=</span> post<span class="token punctuation">.</span>PostId <span class="token punctuation">}</span><span class="token punctuation">,</span> post<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

Retrieving Related Entities Using LINQ

Now that you’re able to save those entities to the DB, you should now be able to retrieve them. This can be done by including the related entity in your LINQ-Entities query. The Include() method allows you to get the associated entity in EF Core.

<span class="token punctuation">[</span>HttpGet<span class="token punctuation">]</span>
        <span class="token keyword">public</span> <span class="token keyword">async</span> Task<span class="token operator">&lt;</span>ActionResult<span class="token operator">&lt;</span>IEnumerable<span class="token operator">&lt;</span>Post<span class="token operator">&gt;</span><span class="token operator">&gt;</span><span class="token operator">&gt;</span> <span class="token function">GetPosts</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            <span class="token keyword">return</span> <span class="token keyword">await</span> _context<span class="token punctuation">.</span>Posts<span class="token punctuation">.</span><span class="token function">Include</span><span class="token punctuation">(</span>a <span class="token operator">=</span><span class="token operator">&gt;</span> a<span class="token punctuation">.</span>Author<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">ToListAsync</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

Conclusion

Creating One-Many Associations in EF Core is simple. These can be handled by just using properties on the Entity and then creating the associated query in LINQ. If you’re interested in learning more, please sign up for our codebrains.io videos or check out the official Microsoft Documentation.

Codebrains Newsletter

Get weekly dev news and tutorials.

Powered by ConvertKit