实体框架4.1代码优先 - 每个层次结构的表没有判别器列

时间:2011-09-12 09:22:05

标签: c# entity-framework-4.1

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

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'

任何人都可以帮我解决如何针对同一个数据库表使用不同模型的问题。请不要提出其他解决方案。

2 个答案:

答案 0 :(得分:4)

这是不可能的。你滥用实体继承。

首先,你没有没有鉴别器列的TPH,因为你永远不会有两个实体映射到同一个数据库记录。这意味着您在数据库中的记录可能只是UserUserFull,但从来都不是。{/ p>

您应该在实体和视图模型之间有所不同。那两个不一样。实体是您想要持久化的,它是完整的数据集合。视图模型是视图上显示的一个或多个实体的子集。

在您的情况下,最明显的解决方案是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进行映射。

答案 1 :(得分:0)

使用

装饰派生类
[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();
        }
    }
}