How do I implement a simple "complex type" in Entity Framework Core 2/C#?

.net-core c# entity-framework-core

Question

I'm using Entity Framework and .Net Core 2.0 for the first time (I'm also pretty new to C#, but I've been using the traditional .Net Framework & VB since version 1... so I'm no newbie to .Net development), and I've already run into a problem creating my database.

Take this simple scenario: I want to store some information about some electric pumps. Two of the properties are a min/max type range, so I've implemented these as a simple class, thus:

public class Pump
{
    [Key]
    public int pumpId { get; set; }
    public string pumpName { get; set; }
    public int pumpControlChannel { get; set; }
    public MinMax normalCurrent { get; set; }
    public MinMax normalFlowRate { get; set; }
}

[ComplexType]
public class MinMax
{
    public int min { get; set; }
    public int max { get; set; }
}

As you can see, I've tried the [ComplexType] decorator, to no avail.

Anyway, now create a dead simple DBContext class to manage my Pumps class. I'm using Sqlite:

public class EFDB : DbContext
{
    public DbSet<Pump> pumps { get; private set; }

    private static DbContextOptions GetOptions(string connectionString)
    {
        var modelBuilder = new DbContextOptionsBuilder();
        return modelBuilder.UseSqlite(connectionString).Options;
    }

    public EFDB(string connectionString) : base(GetOptions(connectionString)) { }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        try
        {
            // modelBuilder.ComplexType<MinMax>();      // ComplexType not recognised
            base.OnModelCreating(modelBuilder);
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debugger.Break();
        }
    }

}

and lastly a simple static class to call it (I embeded it in a bigger program... to duplicate this problem you could just stick the code lines into program.cs):

public static class TryMe
{
    public static void MakeMeFail()
    {
        using (var db = new EFDB("FileName=C:\\temp\\test_effail.db"))
        {
            try
            {
                db.Database.EnsureCreated();
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debugger.Break();   // If we hit this line, it fell over
            }
        }
        System.Diagnostics.Debugger.Break();   // If we hit this line, it worked.
    }
}

Just call TryMe.MakeMeFail(), the code fails at db.Database.EnsureCreated().

From everything I've read, [ComplexType] should do what I want... but it Just Doesn't. Nor can I find modelBuilder.ComplexType<T> anywhere.

It may just be a library reference I'm missing...? The above code uses the following:

using System;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

However, NONE of the documentation/examples I can find anywhere show which libraries need referencing!

Thanks in advance.

[PS: Apologies to those who already saw this question, I'm using EF Core 2.0, NOT EF6]

1
4
5/28/2018 7:04:16 PM

Accepted Answer

Typical... it's always the way, isn't it? 5 minutes after posting, you discover the answer to your own question....

The answer, in this case, can be found here:

https://docs.microsoft.com/en-us/ef/core/modeling/owned-entities

EF Core calls this sort of entity an "owned" entity, rather than a "complex type".

Simply adding these lines to `OnModelCreating' fixed the issue:

modelBuilder.Entity<Pump>().OwnsOne(p => p.normalCurrent);
modelBuilder.Entity<Pump>().OwnsOne(p => p.normalFlowRate);

The database now creates (correctly, I think, I haven't verified that yet).

2
5/28/2018 7:13:31 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow