Tag Archives: Entity Framework

EF Core Relationships in ASP .NET Core 3.1

By Shahed C on February 3, 2020

This is the fifth of a new series of posts on ASP .NET Core 3.1 for 2020. In this series, we’ll cover 26 topics over a span of 26 weeks from January through June 2020, titled ASP .NET Core A-Z! To differentiate from the 2019 series, the 2020 series will mostly focus on a growing single codebase (NetLearner!) instead of new unrelated code snippets week.

Previous post:

NetLearner on GitHub:

In this Article:

E is for EF Core Relationships

In my 2018 series, we covered EF Core Migrations to explain how to add, remove and apply Entity Framework Core Migrations in an ASP .NET Core web application project. In this article, we’ll continue to look at the newer 2020 NetLearner project, to identify entities represented by C# model classes and the relationships between them.

NOTE: Please note that NetLearner is a work in progress as of this writing, so its code is subject to change. The UI web apps still needs work (and will be updated at a later date) but the current version has the following models with the relationships shown below:

NetLearner database diagram
NetLearner database diagram

Classes and Relationships

The heart of the application is the LearningResource class. This represents any online learning resource, such as a blog post, single video, podcast episode, ebook, etc that can be accessed with a unique URL.

public class LearningResource
{
    public int Id { get; set; }

    [DisplayName("Resource")]
    public string Name { get; set; }


    [DisplayName("URL")]
    [DataType(DataType.Url)]
    public string Url { get; set; }

    public int ResourceListId { get; set; }
    [DisplayName("In List")]
    public ResourceList ResourceList { get; set; }

    public ContentFeed ContentFeed { get; set; }

    public List<LearningResourceTopicTag> LearningResourceTopicTags { get; set; }
} 

The ContentFeed class represents the RSS Feed (or channel information) for an online resource, a URL that can be used to retrieve more information about the online resource, if available.

public class ContentFeed
{
    public int Id { get; set; }

    [DisplayName("Feed URL")]
    public string FeedUrl { get; set; }

    public int LearningResourceId { get; set; }
    public LearningResource LearningResource { get; set; }
}

The ResourceList class represents a logical container for learning resources in the system. It is literally a list of items, where the items are your learning resources.

public class ResourceList
{
    public int Id { get; set; }

    public string Name { get; set; }

    public List<LearningResource> LearningResources { get; set; }
} 

The TopicTag class represents a single “tag” value that can be used to categorize online resources. Possibly values could be “.NET Core”, “ASP.NET Core” and so on.

public class TopicTag
{
    public int Id { get; set; }

    [DisplayName("Tag")]
    public string TagValue { get; set; }

    public List<LearningResourceTopicTag> LearningResourceTopicTags { get; set; }
} 

At this point, you may have noticed both the LearningResource and TopicTag classes contain a List<T> property of LearningResourceTopicTag. If you browse the database diagram, you will notice that this table appears as a connection between the two aforementioned tables, to establish a many-to-many relationship. (more on this later)

The following diagram shows an example of how the a LearningResource (e.g. link to a doc/video) is a part of a ResourceList, while each LearningResource also has a link back to its root site, channel or RSS feed (via ContentFeed).

One to One

Having looked through the above entities and relationships, we can see that each LearningResource has a ContentFeed. This is an example of a 1-to-1 relationship. For example:

  • Learning Resource = Wake Up and Code! blog site
  • Content Feed = RSS Feed for blog site

In the two classes, we see the following code:

public class LearningResource
{
public int Id { get; set; }

[DisplayName("Resource")]
public string Name { get; set; }


[DisplayName("URL")]
[DataType(DataType.Url)]
public string Url { get; set; }

public int ResourceListId { get; set; }
[DisplayName("In List")]
public ResourceList ResourceList { get; set; }

public ContentFeed ContentFeed { get; set; }

public List<LearningResourceTopicTag> LearningResourceTopicTags { get; set; }
}
public class ContentFeed
{
public int Id { get; set; }

[DisplayName("Feed URL")]
public string FeedUrl { get; set; }

public int LearningResourceId { get; set; }
public LearningResource LearningResource { get; set; }
}

Each Learning Resource has a corresponding Content Feed, so the LearningResource class has a property for ContentFeed. That’s pretty simple. But in the  ContentFeed class, you don’t necessarily need a property pointing back to the  LearningResource . In fact, all you need is a  LearningResourceId property. EF Core will ensure that LearningResource.Id points to ContentFeed.LearningResourceId in the database. But to help with object-property navigation in your code, it is useful to include an actual LearningResource object in the ContentFeed class to point back to LearningResource.

One to One Relationship
One to One Relationship

Another way of looking at the One-to-One relationship is to view the constraints of each database entity in the visuals below. Note that both tables have an Id field that is a Primary Key (inferred by EF Core) while the ContentFeeds table also has a Foreign Key for the LearningResourceId field used for the constraint in the relationship.

LearningResources table
LearningResources table
ContentFeeds table
ContentFeeds table
One to One Relationship
One to One Relationship

One to Many

Next, let’s take a look at the One-to-Many relationship for each ResourceList that has zero or more LearningResources. For example:

  • Resource List = ASP .NET Core Blogs (parent container)
  • Learning Resource = ASP .NET Core A-Z Blog Series (single URL)

In the two classes, we see the following code:

public class ResourceList
{
public int Id { get; set; }

public string Name { get; set; }

public List<LearningResource> LearningResources { get; set; }
}
public class LearningResource
{
public int Id { get; set; }

[DisplayName("Resource")]
public string Name { get; set; }


[DisplayName("URL")]
[DataType(DataType.Url)]
public string Url { get; set; }

public int ResourceListId { get; set; }
[DisplayName("In List")]
public ResourceList ResourceList { get; set; }

public ContentFeed ContentFeed { get; set; }

public List<LearningResourceTopicTag> LearningResourceTopicTags { get; set; }
}

Each Resource List has zero or more Learning Resources, so the ResourceList class has a List<T> property for LearningResources. This is even simpler than the previously described 1-to-1 relationship. In the LearningResource class, you don’t necessarily need a property pointing back to the ResourceList. But once again, to help with object-property navigation in your code, it is useful to include an actual ResourceList object in the LearningResource class to point back to ResourceList.

One to Many Relationship
One to Many Relationship

Another way of looking at the One-to-Many relationship is to view the constraints of each database entity in the visuals below. Note that both tables have an Id field that is a Primary Key (once again, inferred by EF Core) while the ResourceLists table also has a Foreign Key for the  ResourceListsId field used for the constraint in the relationship.

One to Many Constraint
One to Many Constraint

Many to Many

Finally, let’s also take a look at a Many-to-Many relationship, for each TopicTag and LearningResource, either of which can have many of the other. For example:

  • Topic Tag = “ASP .NET Core” (tag as a text description)
  • Learning Resource = Specific blog post on site (single URL)

This relationship is a little more complicated than all of the above, as we will need a “join table” to connect the two tables in question. Not only that, we will have to describe the entity in the C# code with connections to both tables we would like to connect with this relationship.

In the two classes we would like to connect, we see the following code:

public class TopicTag
{
    public int Id { get; set; }

    [DisplayName("Tag")]
    public string TagValue { get; set; }

    public List<LearningResourceTopicTag> LearningResourceTopicTags { get; set; }
} 
public class LearningResource
{
public int Id { get; set; }

[DisplayName("Resource")]
public string Name { get; set; }


[DisplayName("URL")]
[DataType(DataType.Url)]
public string Url { get; set; }

public int ResourceListId { get; set; }
[DisplayName("In List")]
public ResourceList ResourceList { get; set; }

public ContentFeed ContentFeed { get; set; }

public List<LearningResourceTopicTag> LearningResourceTopicTags { get; set; }
}

Next, we have the LearningResourceTopicTag class as a “join entity” to connect the above:

public class LearningResourceTopicTag
{
    public int LearningResourceId { get; set; }
    public LearningResource LearningResource { get; set; }

    public int TopicTagId { get; set; }
    public TopicTag TopicTag { get; set; }

}

This special class has the following properties:

  • LearningResourceId: integer value, pointing back to LearningResource.Id
  • LearningResource: optional “navigation” property, reference back to connected LearningResource entity
  • TopicTagId: integer value, pointing back to TopicTag.Id
  • TopicTag:  optional “navigation” property, reference back to connected TopicTag entity

To learn more about navigation properties, check out the official docs at:

Many to Many Relationship
Many to Many Relationship

Another way of looking at the Many-to-Many relationship is to view the constraints of each database entity in the visuals below. Note that the two connected tables both have an Id field that is a Primary Key (yes, inferred by EF Core!) while the LearningResourceTopicTag table has a Composite Key for the TopicTagId and LearningResourceId fields used for the constraints in the relationship.

Constraints for LearningResources
Constraints for LearningResources
 Constraints for TopicTags
Constraints for TopicTags

The composite key is described in the LibDbContext class inside the OnModelCreating() method:

public class LibDbContext : IdentityDbContext
{
    ...
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
       ...
       modelBuilder.Entity<LearningResourceTopicTag>()
        .HasKey(lrtt => new { lrtt.LearningResourceId, lrtt.TopicTagId });
    }
}

Here, the HasKey() method informs EF Core that the entity LearningResourceTopicTag has a composite key defined by both LearningResourceId and TopicTagId.

References

For more information, check out the list of references below.

For detailed tutorials that include both Razor Pages and MVC, check out the official tutorials below:

Summarizing Build 2019 + SignalR Service for ASP .NET (Core) Developers

By Shahed C on May 14, 2019

This is the nineteenth of a series of posts on ASP .NET Core in 2019. In this series, we’ll cover 26 topics over a span of 26 weeks from January through June 2019, titled A-Z of ASP .NET Core!

ASPNETCoreLogo-300x267 A – Z of ASP .NET Core!

In this Article:

S is for Summarizing Build 2019 (and SignalR Service!)

For the letter S, I was originally thinking of an article dedicated to SignalR Service. However, Microsoft’s annual Build Conference just happened at the time of this writing. So this week’s post will focus on Summarizing Build 2019 for ASP .NET (Core) Developers, followed by a sneak peek of SignalR Service at the end.

The biggest news for .NET Developers is that .NET Core is the future of .NET, going forward. Furthermore, .NET Core vNext will be named .NET 5, a unified platform for all .NET developers (.NET Framework, Xamarin/Mono and .NET Core).

The GIF below was generated from the .NET Overview session at Build 2019 to illustrate this future:

.NET Roadmap, 2019 and Beyond

.NET Roadmap, from 2014 through 2016, then 2019 and Beyond

Build 2019 for .NET Developers

The quickest to way to catch up on Build 2019 content is to watch all the relevant videos. But how do you know which ones to watch? Well, if you’re a .NET developer, I’ve put together a handy video playlist specifically for .NET Developers (including ASP .NET Core Developers).


Your key takeaways from new announcements should include:

  • .NET Core is the future of .NET: If you’ve already started working with .NET Core, that’s great! If you’re starting a new project, you should consider .NET Core.
  • .NET Framework will continue to be supported: If you have any existing applications on .NET Framework (Windows-only), you can keep those on .NET Framework.
  • .NET Releases will become more predictable: Starting with .NET 5.0, there will be 1 major release every year,  after which each even-numbered release (6.0, 8.0, etc) will come with LTS (Long-Term Support).

In 2019, the expected schedule for .NET Core 3.x is as follows:

  • July 2019: .NET Core 3.0 RC (Release Candidate)
  • September 2019: .NET Core 3.0 (includes ASP .NET Core 3.0)
  • November 2019: .NET Core 3.1 (LTS)

In 2020 and beyond, the expected schedule for .NET Core 5+ is shown below:

  • Early to mid 2020: .NET 5.0 Preview 1
  • November 2020: .NET 5.0
  • November 2021: .NET 6.0 (LTS)
  • November 2022: .NET 7.0
  • November 2023: .NET 8.0 (LTS)

Minor releases (e.g. 5.1, etc) will be considered only if necessary. According to the official announcement, the first preview of .NET 5.0 should be available within the first half of 2020.

NOTE: The upcoming .NET 5.0 should not be confused with the so-called “ASP .NET 5” which was the pre-release name for ASP .NET Core 1.0 before the product was first released in 2016. Going forward, the name of the unified framework is simply .NET 5, without the need for a trailing “Core” in the name.

What’s New in .NET Core 3.0 (Preview 5)

As of May 2019, .NET Core 3.0 is in Preview 5, is expected to be in RC in July 2019, to be followed by a full release in September 2019. This includes ASP .NET Core 3.0 for web development (and more!). For my first look at .NET Core 3.0, you may browse through this earlier post in this series:

The primary themes of .NET Core 3.0 are:

  1. Windows desktop apps: while this is usually not a concern for ASP .NET Core web application developers, it’s good to know that Windows developers can start using .NET Core right away.
  2. Full-stack web dev: Blazor is no longer experimental and its latest preview allows developers to use C# for full-stack web development. More info at: https://blazor.net
  3. AI & ML: Not just buzzwords, Artificial Intelligence and Machine Learning are everywhere. ML.NET 1.0 is now available for C# developers to join this exciting new area of software development. More info at: dot.net/ml
  4. Big Data: .NET for Apache Spark is now in Preview, available on Azure Databricks and Azure HDInsight. More info at: dot.net/spark

For more information on Blazor, you may browse through  this earlier post in this series:

A lot has changed with Blazor in recent months, so the above post will be updated after Core 3.0 is released. In the meantime, check out the official Blazor session from Build 2019.


What’s New in ASP.NET Core 3.0 (Preview 5)

What about ASP .NET Core 3.0 in Preview 5? In the Preview 5 announcement, you can see a handful of updates for this specific release. This includes the following:

  • Easy Upgrade: to upgrade from an earlier preview, update the package reference in your .csproj project file to the latest version (3.0.0-preview5-19227-01)
  • JSON Seralization: now includes support for reading/writing JSON using System.Text.Json. This is part of the built-in JSON support mentioned in the official writeup for .NET Core 3.0 Preview 5.
  • Integration with SignalR: Starting with this release, SignalR clients and servers will now use the aforementioned System.Text.Json as the default Hub protocol. You can read more about this in the SignalR section of the Migration guide for 2.x to 3.0.
  • Continued NewtonsoftJson support: In case you need to switch back to NewtonSoft.Json (previously the default option for the SignalR Hub), the instructions are provided in the aforementioned Migration guide and the announcement. Note that NewtonSoft.Json needs to be installed as a NuGet package.

There has been a lot of development in ASP .NET Core 3.0 in previous Preview releases, so you can refer to my earlier posts in the series for more info:

Here are links to all preview notes if you need a refresher on what was new in each Preview:

NOTE: Changes from each preview to the next is usually cumulative. However, please note that Blazor went from experimental to preview in April 2019, and is now called Blazor on both the client and server. Previously, server-side Blazor was temporarily renamed to Razor Components, but then it was changed back to server-side Blazor.

What’s Next for .NET Core (.NET Core vNext = .NET 5!)

So, what’s next for .NET Core? First of all, the next major version won’t be called .NET Core, as we now know. With the upcoming release of .NET 5, you can now rest assured that all your investment into .NET Core will carry over into the future unified release.

Imagine taking the cross-platform .NET Core and bringing in the best of Mono for a single BCL (Base Class Library implementation). You may recall that .NET Standard was introduced when there were multiple versions of .NET (Framework, Mono/Xamarin and Core). Going forward, .NET Standard will continue to exist and .NET 5 will adhere to .NET Standard.

DotNet5-Layers-Heading

Compare the unified diagram with the various versions of .NET Framework, .NET Core and Mono over the years:

DotNet-VersionHistory

Note that not everything in the world of .NET today will make it into .NET 5. Not to worry though, as there are various recommended alternatives for all .NET developers. Take the following technologies, for example:

  • Web Forms: As you may have noticed, ASP .NET Web Forms have not been ported to ASP .NET Core. Instead of Web Forms, developers may consider Blazor as their choice of web application development.
  • WCF: Although Web API has been included in ASP .NET Core, there is no option for WCF. Going forward, you may use gRPC as an alternative.

Migration Guides for the above scenarios will be provided at a later date.

EF 6.3 for .NET Core, SqlClient & Diagnostics

In addition to ASP .NET Core itself, there are other tools and technologies that may be useful for ASP .NET Core developers. That may include (but is not limited to) the following):

  • Entity Framework 6.3: In addition to the EF Core running on .NET Core, EF 6.x was known to run on the Windows-only .NET Framework 4.x but not on .NET Core. Going forward, EF 6.3 will run on .NET Core 3.0 across platforms.
  • SqlClient: Instead of replacing the existing System.Data.SqlClient package directly, the new Microsoft.Data.SqlClient (available on NuGet) will support both .NET Core and .NET Framework.
  • .NET Core Diagnostic Tools: Making use of .NET Core Global Tools, a new suite of tools will help developers with diagnostics and troubleshooting ofperf issues.

From the tools‘ GitHub page, the following tools are currently available, with the following descriptions:

  • dotnet-dump: “Dump collection and analysis utility.”
  • dotnet-trace: “Enable the collection of events for a running .NET Core Application to a local trace file.”
  • dotnet-counters: “Monitor performance counters of a .NET Core application in real time.”

SignalR Service (Sneak Peek)

Finally, let’s take a quick peek at the all-new SignalR Service.

SignalR-Service-Portal

  • Who can use this: Web developers who want to build real-time features can get started with a variety of official Quickstart guides: ASP .NET Core, JavaScript, C#, Java and REST API

If you’re already familiar with using SignalR, switching to using Azure SignalR Service is as easy as 1-2-3.

  1. Append a call to .AddAzureSignalR() to AddSignalR() in the ConfigureServices() method of your Startup class.
  2. Replace the call to UseSignalR() with a call to UseAzureSignalR() in your Configure() method
  3. Ensure that your environment’s connection string is set correctly for the key “Azure:SignalR:ConnectionString“.

In the ConfigureServices() method, this is what your code should look like:

public void ConfigureServices(IServiceCollection services)
{
   // ...
   services.AddMvc();
   services.AddSignalR().AddAzureSignalR();
} 

In the Configure() method, this is what your code should look like:

app.UseAzureSignalR(routes =>
{
 routes.MapHub<HubClassName>("/HubRouteName");
});

Your connection string (in your environment or User Secrets) may look like the following:

"Azure:SignalR:ConnectionString": "Endpoint=<yourendpoint>;AccessKey=<yourkey>;"

For a detailed tutorial for ASP .NET Core developers, try this official guide:

After the A-Z weekly series is complete, stay tuned for monthly blog posts about cool things .NET developers can do in Azure. This will include a more in-depth look at SignalR Service in a future writeup, including guidance for both web and mobile developers.

References for Build 2019 Announcements

References for SignalR Service

 

EF Core Relationships in ASP .NET Core

By Shahed C on February 4, 2019

This is the fifth of a new series of posts on ASP .NET Core for 2019. In this series, we’ll cover 26 topics over a span of 26 weeks from January through June 2019, titled A-Z of ASP .NET Core!

ASPNETCoreLogo-300x267 A – Z of ASP .NET Core!

In this Article:

E is for EF Core Relationships

In my 2018 series, we covered EF Core Migrations to explain how to add, remove and apply Entity Framework Core Migrations in an ASP .NET Core web application project. In this article, we’ll continue to look at the NetLearner project, to identify entities represented by C# model classes and the relationships between them.

NOTE: Please note that NetLearner is a work in progress as of this writing, so its code is subject to change. The UI still needs work (and will be updated at a later date) but the current version has the following models with the relationships shown below:

NetLearner database diagram

NetLearner database diagram

Classes and Relationships

The heart of the application is the LearningResource class. This represents any online learning resource, such as a blog post, single video, podcast episode, ebook, etc that can be accessed with a unique URL.

public class LearningResource : InternetResource
{
    public List<LearningResourceItemList> LearningResourceItemLists
    {
        get; set;
    }
}

The abstract class InternetResource defines the common properties (e.g. Id, Name and Url) found in any Internet resource, and is also used by other classes ResourceRoot and RssFeed.

public abstract class InternetResource
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Url { get; set; }
}

The ResourceRoot class represents a root-level resource (e.g. a blog home or a podcast website) while the RssFeed class represents the RSS Feed for an online resource.

public class ResourceRoot: InternetResource
{
    public RssFeed RssFeed { get; set; }
    public List<LearningResource> LearningResources { get; set; }
}
public class RssFeed: InternetResource
{
    public int ResourceRootId { get; set; }
}

The ItemList class represents a logical container for learning resources in the system. It is literally a list of items, where the items are your learning resources.

public class ItemList
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<LearningResourceItemList> LearningResourceItemLists
    {
        get; set;
    }
}

At this point, you may have noticed both the LearningResource and ItemList classes contain a List<T> property of LearningResourceItemList. If you browse the database diagram, you will notice that this table appears as a connection between the two aforementioned tables, to establish a many-to-many relationship. (more on this later)

The following diagram shows an example of how the a LearningResource is a part of a list (which is a part of a ResourceCatalog), while each LearningResource also has a ResourceRoot.

NetLearner example

NetLearner example

One to One

Having looked through the above entities and relationships, we can see that each ResourceRoot has an RssFeed. This is an example of a 1-to-1 relationship. For example:

  • Resource Root = Wake Up and Code! blog site
  • Rss Feed = RSS Feed for blog site

In the two classes, we see the following code:

public class ResourceRoot: InternetResource
{
    public RssFeed RssFeed { get; set; }
    public List<LearningResource> LearningResources { get; set; }
}
public class RssFeed: InternetResource
{
    public int ResourceRootId { get; set; }
}

Each Resource Root has a corresponding Rss Feed, so the ResourceRoot class has a property for RssFeed. That’s pretty simple. But in the RssFeed class, you don’t need a property pointing back to the ResourceRoot. In fact, all you need is a ResourceRootId property. EF Core will ensure that ResourceRoot.Id points to RssFeed.ResourceRootId in the database.

One to One Relationships

One to One Relationships

If you’re wondering how these two classes got their Id, Name and Url fields, you may recall that they are both derived from a common abstract parent class (InternetResource) that define all this fields for reuse. But wait a second… why doesn’t this parent class appear in the database? That’s because we don’t need it in the database and have intentionally ommitted it from the list of DBSet<> definitions in the DB Context for the application, found in ApplicationDbContext.cs:

public class ApplicationDbContext : IdentityDbContext
{
...
    public DbSet<ItemList> ItemList { get; set; }
    public DbSet<LearningResource> LearningResource { get; set; }
    public DbSet<ResourceCatalog> ResourceCatalog { get; set; }
    public DbSet<ResourceRoot> ResourceRoot { get; set; }
    public DbSet<RssFeed> RssFeed { get; set; }
...
}

Another way of looking at the One-to-One relationship is to view the constraints of each database entity in the visuals below. Note that both tables have an Id field that is a Primary Key (inferred by EF Core) while the RssFeed table also has a Foreign Key for the ResourceRootId field used for the constraint in the relationship.

RssFeed table

RssFeed table

ResourceRoot Table

ResourceRoot Table

NetLearner-Db-ResourceRoot-RssFeed

1-to-1 Relationship: ResourceRoot.Id points to RssFeed.ResourceRootId

One to Many (Example 1)

Next, let’s take a look at the One-to-Many relationship for each ResourceCatalog that has zero or more ItemLists. For example:

  • Resource Catalog = ASP .NET Core Blogs
  • Item List = ASP .NET Core A-Z Blog Series

In the two classes, we see the following code:

public class ResourceCatalog
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<ItemList> ItemLists { get; set; }
}
public class ItemList
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<LearningResourceItemList> LearningResourceItemLists
    {
        get; set;
    }
}

Each Resource Catalog has zero or more Item Lists, so the ResourceCatalog class has a List<T> property for ItemLists. This is even simpler than the previously described 1-to-1 relationship. In the ItemList class, you don’t need a property pointing back to the ResourceCatalog.

One-to-Many Relationship

One-to-Many Relationship

Another way of looking at the One-to-Many relationship is to view the constraints of each database entity in the visuals below. Note that both tables have an Id field that is a Primary Key (once again, inferred by EF Core) while the ItemList table also has a Foreign Key for the ResourceCatalogId field used for the constraint in the relationship.

NetLearner-Db-ResourceCatalog-ItemList-Constraint

1-to-Many Relationship: ResourceCatalog.Id points to ItemList.ResourceCatalogId

One to Many (Example 2)

Let’s also take a look at another One-to-Many relationship, for each ResourceRoot that has zero or more LearningResources. For example:

  • Resource Root = Wake Up and Code! blog site
  • Learning Resource = Specific blog post on site

In the two classes, we see the following code:

public class ResourceRoot: InternetResource
{
    public RssFeed RssFeed { get; set; }
    public List<LearningResource> LearningResources { get; set; }
}
public class LearningResource : InternetResource
{
    public List<LearningResourceItemList> LearningResourceItemLists
    {
        get; set;
    }
}

Each Resource Root has zero or more Learning Resources, so the ResourceRoot class has a List<T> property for LearningResources. This is just as simple as the aforementioned 1-to-many relationship. In the LearningResource class, you don’t need a property pointing back to the ResourceRoot.

Relationship between ResourceRoot and LearningResource

ResourceRoot and LearningResource

Another way of looking at the One-to-Many relationship is to view the constraints of each database entity in the visuals below. Note that both tables have an Id field that is a Primary Key (inferred by EF Core, as you should know by now) while the LearningResource table also has a Foreign Key for the ResourceRootId field used for the constraint in the relationship.

1-to-Many Constraint

1-to-Many Constraint for ResourceRoot and LearningResource

Many to Many

Finally, let’s also take a look at a Many-to-Many relationship, for each ItemList and LearningResource, either of which can have many of the other. For example:

  • Item List = ASP .NET Core A-Z Blog Series
  • Learning Resource = Specific blog post on site

This relationship is a little more complicated than all of the above, as we will need a “join table” to connect the two tables in question. Not only that, we will have to describe the entity in the C# code with connections to both tables we would like to connect with this relationship.

If you’re wondering when EF Core will support this type of relationship without a join table, check out the following GitHub issue discussions:

Specifically, take a look at this comment: “Current plan for 3.0 is to implement skip-level navigation properties as a stretch goal. If property bags (#9914) also make it into 3.0, enabling a seamless experience for many-to-many could become easier.

In the two classes we would like to connect, we see the following code:

public class ItemList
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<LearningResourceItemList> LearningResourceItemLists
    {
        get; set;
    }
}
public class LearningResource : InternetResource
{
    public List<LearningResourceItemList> LearningResourceItemLists
    {
        get; set;
    }
}

Next, we have the LearningResourceItemList class as a “join entity” to connect the above:

public class LearningResourceItemList
{
    public int LearningResourceId { get; set; }
    public LearningResource LearningResource { get; set; }
    public int ItemListId { get; set; }
    public ItemList ItemList { get; set; }
}

This special class has the following properties:

  • LearningResourceId: integer value, pointing back to LearningResource.Id
  • LearningResource: optional “navigation” property, reference back to connected LearningResource entity
  • ItemListId: integer value, pointing back to ItemList.Id
  • ItemList:  optional “navigation” property, reference back to connected ItemList entity

To learn more about navigation properties, check out the official docs at:

Many-to-Many Relationship

Many-to-Many Relationship

Another way of looking at the Many-to-Many relationship is to view the constraints of each database entity in the visuals below. Note that the two connected tables both have an Id field that is a Primary Key (yes, inferred by EF Core!) while the LearningResourceItemList table has a Composite Key for the ItemListId and LearningResourceId fields used for the constraints in the relationship.

The composite key is described in the ApplicationDbContext class inside the OnModelCreating() method:

public class ApplicationDbContext : IdentityDbContext
{
    ...
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<LearningResourceItemList>()
            .HasKey(r => new { r.LearningResourceId, r.ItemListId });
        base.OnModelCreating(modelBuilder);
    }
}

Here, the HasKey() method informs EF Core that the entity LearningResourceItemList has a composite key defined by both LearningResourceId and ItemListId.

References

For more information, check out the list of references below.

For detailed tutorials that include both Razor Pages and MVC, check out the official tutorials below:

 

 

ASP.NET Core 2.1 at CMAP August 2018

By Shahed C on August 8, 2018

I presented ASP.NET Core 2.1 at CMAP 2018.1 on Tue August 7, 2018. Here is the presentation material with the slides, links and my contact information. I’ve also included some links to more information to help answer some questions from the audience.

asp-net-logo

Download PPTX or view slideshow below

SlideShare: https://www.slideshare.net/shahedC3000/aspnet-core-21-the-future-of-web-apps-109106486

The new and improved ASP .NET Core 2.1 introduces some great new capabilities, the ability to host on multiple server platforms, and a number of new tools that you will want to get familiar with. Learn about the future of ASP.NET Core MVC, Web API, Razor Web Pages, SignalR, .NET Core Tools and Visual Studio 2017!!

Here are some links that mention information that may be useful to attendees who asked questions about the following:

Daniel Roth’s summary of what’s new in ASP .NET Core 2.1

OWIN in ASP .NET Core

Oracle with EF Core in ASP .NET Core

  • Excerpt: “The Oracle .NET team has announced they are planning to release a first-party provider for EF Core 2.0 approximately in the third quarter of 2018. See their statement of direction for .NET Core and Entity Framework Core for more information. Please direct any questions about this provider, including the release timeline, to the Oracle Community Site.”
  • From Article: Database Providers – EF Core | Microsoft Docs
  • Link: https://docs.microsoft.com/en-us/ef/core/providers/#future-providers

Using IdentityServer (via a Nuget package) in ASP .NET Core web app with Angular:

Video course on ASP .NET Core app with Angular using Identity, via Lynda

p.s. when creating a new Angular web project from VS2017, it appears that the Authentication option is not available, so we’re not able to add Identity support during file creation in an Angular app, the way we do it with ASP .NET MVC/Razor web apps. 

I also ran the following command in the command line, to attempt to create an Angular web app with the –auth flag for Individual authentication, but this is not a valid option.

>dotnet new angular --auth Individual -o AngWebWithAuth

Compare with a regular ASP .NET MVC web app with the — auth flag, which works with no issues.

>dotnet new mvc --auth Individual -o MvcWebWithAuth

The “New Project” dialog in VS2017 has a link to the following page for more info on Identity options for OSS web projects:

ang-auth-options

The list mentions the following options:

 

ASP.NET Core 2.1 at NoVA Code Camp 2018.1

By Shahed C on May 14, 2018

I presented ASP.NET Core 2.1 and Visual Studio 2017 at NoVA Code Camp 2018.1 on Sat May 12, 2018. Here is the presentation material with the slides, links and my contact information.

asp-net-logo

Download PPTX or view slideshow below

SlideShare: https://www.slideshare.net/shahedC3000/aspnet-core-21-the-future-of-web-apps-97080858

The new and improved ASP .NET Core 2.1 introduces some great new capabilities, the ability to host on multiple server platforms, and a number of new tools that you will want to get familiar with. Learn about the future of ASP.NET Core MVC, Web API, Razor Web Pages, SignalR, .NET Core Tools and Visual Studio 2017!!