Skip to content
This repository has been archived by the owner on Dec 3, 2017. It is now read-only.

Connect to Data Using Entity Framework Core

AlekseyMartynov edited this page Jul 1, 2016 · 6 revisions

Ensure that EF Core Dependencies and Tools are Installed

To use Entity Framework Core with SQL Server and scaffolding, make sure that the project.json file contains the following entries:

{
    "dependencies": {
        "Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore": "1.0.0",
        "Microsoft.EntityFrameworkCore.SqlServer": "1.0.0",
        "Microsoft.EntityFrameworkCore.SqlServer.Design": "1.0.0",
        "Microsoft.EntityFrameworkCore.Tools": {
            "version": "1.0.0-preview2-final",
            "type": "build"
        }
    },

    "tools": {
        "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final"
    }
}

Generate EF Core Data Classes from an Existing Database

Open a command prompt (cmd or PowerShell) at the project root directory and execute the following command:

dotnet ef dbcontext scaffold CONNECTION_STRING PROVIDER -a -c CONTEXT_CLASS -o OUTPUT_DIR

Substitute CONNECTION_STRING, PROVIDER, CONTEXT_CLASS, OUTPUT_DIR placeholders with required values.

For example, the command below generates a model for the well-known Northwind database running on a local SQL Server Express instance:

dotnet ef dbcontext scaffold "Data Source=.\SQLEXPRESS; Initial Catalog=NORTHWND; Integrated security=True" Microsoft.EntityFrameworkCore.SqlServer -a -c NorthwindContext -o Models\Northwind

New files should appear in the Models\Northwind directory.

Register a Database Context in the Startup Class

Add the following line at the end of the ConfigureServices method of the Startup class:

public void ConfigureServices(IServiceCollection services) {
    . . .
    
    services
        .AddEntityFrameworkSqlServer()
        .AddDbContext<NorthwindContext>();
}

Add an MVC Action to Serve Data in a RESTful Way

Add a new Controller class, and inject the NorthwindContext via the constructor as follows:

public class NorthwindController : Controller {
    NorthwindContext _nwind;

    public NorthwindController(NorthwindContext nwind) {
        _nwind = nwind;
    }
}

NOTE. The use of Dependency Injection is not only convenient but also guarantees proper lifetime of objects.

DevExtreme ASP.NET Core Tag Helpers take advantage of the DevExtreme.AspNet.Data library which makes possible creating RESTful data end-points compatible with DevExtreme widgets, literally with a single line of code.

For example, the following code is enough to expose the Orders collection for read-only access:

[HttpGet]
public object Orders(DataSourceLoadOptions loadOptions) {
    return DataSourceLoader.Load(_nwind.Orders, loadOptions);
}

Full CRUD

To support all CRUD operations, add three more actions:

[HttpPut]
public IActionResult UpdateOrder(int key, string values) {
    var order = _nwind.Orders.First(o => o.OrderID == key);
    JsonConvert.PopulateObject(values, order);

    if(!TryValidateModel(order))
        return BadRequest(GetFullErrorString());

    _nwind.SaveChanges();

    return Ok();
}

[HttpPost]
public IActionResult InsertOrder(string values) {
    var order = new Order();
    JsonConvert.PopulateObject(values, order);

    if(!TryValidateModel(order))
        return BadRequest(GetFullErrorString());


    _nwind.Orders.Add(order);
    _nwind.SaveChanges();

    return Ok();
}

[HttpDelete]
public void DeleteOrder(int key) {
    var order = _nwind.Orders.First(o => o.OrderID == key);
    _nwind.Orders.Remove(order);
    _nwind.SaveChanges();
}

string GetFullErrorString() {
    var messages = new List<string>();

    foreach(var entry in ModelState.Values) {
        foreach(var error in entry.Errors)
            messages.Add(error.ErrorMessage);
    }

    return String.Join(" ", messages);
}

Of course, instead of using the JsonConvert.PopulateObject utility (a part of the Newtonsoft.Json package), it is possible to implement any custom logic for data editing.

Data-Bind DevExtreme Widgets

Use the <datasource> tag to specify controller and action names, and the primary key field:

<dx-data-grid>
    <datasource controller="Northwind" load-action="Orders" 
                key="orderID" 
                insert-action="InsertOrder" 
                update-action="UpdateOrder" 
                delete-action="DeleteOrder" />    
</dx-data-grid>

Example

A complete example is available in the Samples demo project:

See Also