Featured image of post Using SQL Server Views within Entity Framework Core (Code First Data Annotations)

Using SQL Server Views within Entity Framework Core (Code First Data Annotations)

If you’ve done any serious work involving Entity Framework (EF) Core in the past, there’s a good chance that you’ve worked with Code First Data Annotations when modelling your classes in C#. To summarise, these provide you with an in-line mechanism of describing the various DDL objects that you are referencing from your underlying data source. Typically, this may be required when you need the names, attributes and other general properties of your classes to differ from what your data source is surfacing. They are also an almost mandatory requirement when you want EF Core to handle the creation of your database automatically when deploying out your project for the first time. While I do personally find this approach to be borderline heretical, it is nonetheless a valid means of modelling out a database that is intrinsically bound to your EF Core project. So don’t let me put you off from using it if it will meet your particular requirements.

Now, it’s all well and good saying that something is good, but it’s far more important, I think, to see how it works in action. With this in mind, let’s assume we are adopting a pious approach for our EF Core project - namely, our database is already existing - and we are dealing with a mismatch between our database and class object names. Specifically, suppose we want to expose out a class called MyClass, but our underlying data source is a SQL Server table called MyTable. We would have to utilise the Table annotation, as demonstrated below, to ensure our code can navigate across to our intended location at runtime:

using System;
using System.ComponentModel.DataAnnotations.Schema;

namespace MyEFProject.Classes
{
    [Table("MyTable")]
    public class MyClass
    {
		//Column definitions go here...
    }
}

We can extend this further if we happen to be using custom schemas within our database. So, if we choose to create our MyTable within a schema called Sample, we can adjust the annotation as follows:

using System;
using System.ComponentModel.DataAnnotations.Schema;

namespace MyEFProject.Classes
{
    [Table("MyTable", Schema = "Sample")]
    public class MyClass
    {
		//Column definitions go here...
    }
}

Pretty neat. But what happens if we need to reference a view as opposed to a table instead? I dealt with this requirement recently when building out a read-only OData endpoint using ASP.NET Core MVC and, despite my efforts, I could not locate a valid source to tell me that views are a supported. Well, after experimenting further, I can confirm that it IS possible to do this via the very same Table Annotation used earlier. So, if our SQL Server view is called vw_MyView and exists on the very same schema referenced earlier, here’s how our class would need to look:

using System;
using System.ComponentModel.DataAnnotations.Schema;

namespace MyEFProject.Classes
{
    [Table("vw_MyView", Schema = "Sample")]
    public class MyClass
    {
		//Column definitions go here...
    }
}

And, although I have not tested this myself, it should also be possible for you to then write or update data into the view, in much the same manner as we can write manual SQL queries to do just this.

Using Data Annotations within EF Core can significantly simplify the process for handling situations like the ones described in this post, without needing to write a whole bunch of specialised code instead. If you haven’t already, I will urge you to read through this informative Microsoft Docs article, which talks through in detail the types of things you can do with them. To summarise then, never treat Data Annotations as a one-trick pony. Regardless of whether you are getting EF Core to handle the creation of your database structure automatically or are referencing an existing database, there will be a whole host of options available here to help you along.

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy