.Net Core / EF核心模型(MySQL后端)中忽略数据注释

时间:2017-01-13 13:32:45

标签: asp.net-mvc asp.net-web-api entity-framework-core

我使用.Net Core 1.1和EF Core创建了一个Web API。后端是一个MySQL数据库,所以我在project.json文件中包含了“MySql.Data.EntityFrameworkCore”:“7.0.6-IR31”依赖项。

我的项目中有一个简单的模型。我试图将模型中的列映射到现有数据库中的列。所以我正在使用数据注释。我有这个:

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

namespace PropWorxAPI.Models
    {
        [Table("files")]
        public partial class File
        {
            [Key]
            [Column("file_id")]
            public int FileId { get; set; }
            [Required]
            [Column("file_num")]
            [MaxLength(50)]
            public string FileNum { get; set; }
            [MaxLength(255)]
            public string Description { get; set; }
        }
    }

我希望属性 FileId 映射到数据库中的字段 file_id 。但是,当我运行该项目时,它会抱怨数据库中没有字段 FileId 。这几乎就像我的列映射注释被完全忽略了一样。有任何想法吗?感谢...

以防万一,我在下面包含了我的project.json文件:

{
  "dependencies": {
    "MySql.Data.EntityFrameworkCore": "7.0.6-IR31",
    "Microsoft.AspNetCore.Mvc": "1.1.0",
    "Microsoft.AspNetCore.Routing": "1.1.0",
    "Microsoft.AspNetCore.Server.IISIntegration": "1.1.0",
    "Microsoft.AspNetCore.Server.Kestrel": "1.1.0",
    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0",
    "Microsoft.Extensions.Configuration.FileExtensions": "1.1.0",
    "Microsoft.Extensions.Configuration.Json": "1.1.0",
    "Microsoft.Extensions.Logging": "1.1.0",
    "Microsoft.Extensions.Logging.Console": "1.1.0",
    "Microsoft.Extensions.Logging.Debug": "1.1.0",
    "Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.0",
    "Microsoft.NETCore.App": {
      "version": "1.1.0",
      "type": "platform"
    }
  },

  "tools": {
    "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.1.0-preview4-final"
  },

  "frameworks": {
    "netcoreapp1.0": {
      "imports": [
        "dotnet5.6",
        "portable-net45+win8"
      ]
    }
  },

  "buildOptions": {
    "emitEntryPoint": true,
    "preserveCompilationContext": true
  },

  "runtimeOptions": {
    "configProperties": {
      "System.GC.Server": true
    }
  },

  "publishOptions": {
    "include": [
      "wwwroot",
      "**/*.cshtml",
      "appsettings.json",
      "web.config"
    ]
  },

  "scripts": {
    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
  }
}

2 个答案:

答案 0 :(得分:2)

我也有这个问题,我能找到的唯一解决方案是使用流畅的API来定义映射而不是注释。 E.g。

builder.Entity<Product>().ToTable("product").HasKey(m => m.Id);
builder.Entity<Product>().Property(p => p.DateAdded).HasColumnName("date_added");
builder.Entity<Product>().Property(p => p.ImageUrl).HasColumnName("image_url");

希望很快就能获得对注释的支持。

答案 1 :(得分:0)

我想避免使用Fluent API,因为我更喜欢在实际属性上处理列映射,因此我使用反射构建了自己的列映射。

请参阅OnModelCreating函数中相关部分的代码。

注意我使用的是MySql,代码未经过100%测试。

using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;
using MySQL.Data.EntityFrameworkCore.Extensions;
using System.Reflection;

namespace MyProject
{
    public class DatabaseContext : DbContext
    {
        private string _connectionString;

        public DbSet<Entity> Entities { get; set; }

        public DatabaseContext(string connectionString)
        {
            _connectionString = connectionString;
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseMySQL(_connectionString);
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            // I couldn't get attribute mapping to work, so I
            // had to do the mapping programmatically myself.
            // Ideally we'd remove this code an rely on the
            // built-in code to handle it, but we need to wait
            // for MySql to support mapping in EF Core.

            var type = typeof(Entity);
            var properties = type
                .GetTypeInfo()
                .GetProperties(BindingFlags.Public |
                               BindingFlags.Instance | 
                               BindingFlags.DeclaredOnly);

            foreach (var property in properties)
            {
                System.Console.WriteLine(property.Name);

                var ignore = property.GetCustomAttribute<NotMappedAttribute>();
                if (ignore != null)
                {
                    modelBuilder
                        .Entity(type)
                        .Ignore(property.Name);

                    continue;
                }

                var column = property.GetCustomAttribute<ColumnAttribute>();

                if (column == null)
                {
                    modelBuilder
                        .Entity(type)
                        .Property(property.Name)
                        .HasColumnName(property.Name);

                    continue;
                }

                modelBuilder
                    .Entity(type)
                    .Property(property.Name)
                    .HasColumnName(column.Name);

            }
        }
    }
}