实体框架4.1代码优先-每个层级表没有鉴别列

本文关键字:鉴别 框架 代码 实体 | 更新日期: 2023-09-27 18:08:24

我想在不同的模型中分解一个表,以便在不同的视图中使用。

public class User
{
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
}
public class UserFull : User
{
        public string Street { get; set; }
        public string Country { get; set; }
}
public class theDBtoUse : DbContext
{
    public DbSet<User> User { get; set; }
    public DbSet<UserFull> UserFull { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>().Property(r => r.Id).HasColumnName("user_id");
        modelBuilder.Entity<User>().Property(r => r.FirstName).HasColumnName("user_firstname");
        modelBuilder.Entity<User>().Property(r => r. LastName).HasColumnName("user_lastname");
        modelBuilder.Entity<User>().ToTable("user");
        modelBuilder.Entity<UserFull>().Property(r => r.Street).HasColumnName("user_street ");
        modelBuilder.Entity<UserFull>().Property(r => r.Country).HasColumnName("user_country");
        base.OnModelCreating(modelBuilder);
    }

}

当我使用这个。说它缺少'Discriminator'列

theDBtoUse theDB = new theDBtoUse();
var theUserToMatch = (from r in theDB.UserFull
                                  where r.Street.ToLower() == "astreetname"
                                  select r);
if theUserToMatch () == 0) // throws - Invalid column name 'Discriminator'

谁能帮助我如何使用不同的模型对同一数据库表。请不要提出其他解决方案

实体框架4.1代码优先-每个层级表没有鉴别列

不可能。您正在滥用实体继承。

首先,你不可能有没有discriminator列的TPH,因为你不可能有两个实体映射到同一个数据库记录。这意味着您在数据库中的记录只能是UserUserFull,但永远不能同时是它们。

你应该区分实体和视图模型。这两者不一样。实体是您想要持久化的内容,它是完整的数据集合。视图模型是显示在视图上的一个或多个实体的子集。

在你的情况下,最明显的解决方案是User类与所有字段和投影查询自定义非映射视图为有限的用户视图。

映射实体和全视图模型:

public class User
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Street { get; set; }
    public string Country { get; set; }
}

非映射受限视图模型:

public class UserLimitedView
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

映射:

public class theDBtoUse : DbContext
{
    public DbSet<User> User { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>().Property(r => r.Id).HasColumnName("user_id");
        modelBuilder.Entity<User>().Property(r => r.FirstName).HasColumnName("user_firstname");
        modelBuilder.Entity<User>().Property(r => r. LastName).HasColumnName("user_lastname");
        modelBuilder.Entity<User>().Property(r => r.Street).HasColumnName("user_street ");
        modelBuilder.Entity<User>().Property(r => r.Country).HasColumnName("user_country");
        base.OnModelCreating(modelBuilder);
    }
}
查询:

var data = context.Users
                  .Where(...)
                  .Select(u => new UserLimitedView
                      {
                          Id = u.Id,
                          FirstName = u.FirstName,
                          LastName = u.LastName
                      });
var fullData = context.Users.Where(...);

EF代码首先没有直接映射投影的内置映射支持。在EDMX的情况下,投影可以通过QueryView作为映射的一部分。

装饰你的派生类
[Table("tablename")]

请在下面找到一个完整的项目(只需添加一个app.config)

using System;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.Linq;
namespace Bookstore
{
    public class User
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
    [Table("UsersFull")]
    public class UserFull : User
    {
        public string Street { get; set; }
        public string Country { get; set; }
    }
    public class Context : DbContext
    {
        static Context()
        {
            Database.SetInitializer<Context>(null);
        }
        public DbSet<User> Users { get; set; }
        public DbSet<UserFull> UsersFull { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var context = new Context();
            context.Database.Delete();
            context.Database.Create();

            var userFull = new UserFull { Country = "Alabama", FirstName = "John", LastName = "Capioca", Street = "astreetname" };
            context.UsersFull.Add(userFull);
            context.SaveChanges();
            var theUserToMatch = (from r in context.UsersFull
                                  where r.Street.ToLower() == "astreetname"
                                  select r);
            if (theUserToMatch.Count() != 0)
                Console.WriteLine("Yeah! No Invalid column name 'Discriminator' exception");
            Console.ReadLine();
        }
    }
}