Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Owned types problem in Entity Framework Core 3.0

I have strange behavior of EF Core 3.0 preview4. I have main class:

public enum ClientType
{
    Customer = 0,
    Produces = 1,
}

public class User : IdentityUser<Guid>
{
    public ClientType ClientType { get; set; }
    public SMSCodeInfo SMSCodeInfo { get; set; }
    public string Discriminator { get; set; }
}

In this code SMSCodeInfo is a class:

public class SMSCodeInfo
{ 
    public long Code { get; set; }
    public DateTime Expiration { get; set; }

    public SMSCodeInfo() { }
    public SMSCodeInfo(int days, int hours, int minutes) : this(DateTime.Now.AddDays(days).AddHours(hours).AddMinutes(minutes)) { }
    public SMSCodeInfo(DateTime Expiration)
    {
        this.Expiration = Expiration;
        Code = new Random().Next(100000, 999999);
    }        
}

I tried to add SMSCodeInfo as owned data into the User class by different methods: [Owned] attribute usage, adding code in OnModelCreating(ModelBuilder modelBuilder) method:

modelBuilder.Entity<User>().OwnsOne(o => o.SMSCodeInfo);

But each time I make a migration, I get 2 tables: AspNetUsers with an Identity information about users (I use Asp.net core identity in my project), and AspNetUsers1 table which consists of SMSCodeInfo members. EF Core generates this code for migration and I can't understand "why"!

        migrationBuilder.CreateTable(
            name: "AspNetUsers1",
            columns: table => new
            {
                UserId = table.Column<Guid>(nullable: false),
                Code = table.Column<long>(nullable: false),
                Expiration = table.Column<DateTime>(nullable: false)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_AspNetUsers1", x => x.UserId);
                table.ForeignKey(
                    name: "FK_AspNetUsers1_AspNetUsers_UserId",
                    column: x => x.UserId,
                    principalTable: "AspNetUsers",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.Cascade);
            });

"Additional". I want to have owned data be added in the AspNetUser table, not in a separate table.

P.S. This problem arises for the classes, derived from IdentityUser<>. For other classes in my project code like this modelBuilder.Entity<TOwner>().OwnsOne(o => o.ToBeOwned); works correct and gives correct tables with injected owned types.

like image 610
Dmitriy Avatar asked Apr 18 '26 19:04

Dmitriy


1 Answers

According to Owned Entity Types in EF Core, modelBuilder.Entity<User>().OwnsOne(o => o.SMSCodeInfo); should create the [Owned] entity columns in the Owner table but stangely it creating into a seprate table with a strange name AspNetUsers1.

If you want the [Owned] entity columns should be in a separate table then your configuration should be as follows:

modelBuilder.Entity<User>().OwnsOne(o => o.SMSCodeInfo , sm => 
{
   sm.ToTable("SMSCodeInfo");
});

It will generate as follows:

migrationBuilder.CreateTable(
            name: "SMSCodeInfo",
            columns: table => new
            {
                UserId = table.Column<Guid>(nullable: false),
                Code = table.Column<long>(nullable: false),
                Expiration = table.Column<DateTime>(nullable: false)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_SMSCodeInfo", x => x.UserId);
                table.ForeignKey(
                    name: "FK_SMSCodeInfo_AspNetUsers_UserId",
                    column: x => x.UserId,
                    principalTable: "AspNetUsers",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.Cascade);
            });
like image 90
TanvirArjel Avatar answered Apr 21 '26 12:04

TanvirArjel