EF Linq到实体查询以生成TPC CTP5代码优先实体的UNION [英] EF Linq to entities query generating UNION for TPC CTP5 code-first entity

查看:111
本文介绍了EF Linq到实体查询以生成TPC CTP5代码优先实体的UNION的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下实体:

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class HappyUser : User
{
    public bool IsHappy { get; set; }
}

我正在使用每个具体类型的表(TPC)配置实体,以生成用户表和HappyUser表.我希望HappyUser表包含User类的属性,并且我不希望两个表之间有任何关系.

I am configuring the entities using Table Per Concrete Type (TPC) in order to generate a User table and a HappyUser table. I want the HappyUser table to include the properties of the User class, and I don't want any relationship between the two tables.

我按如下方式配置实体:

I configure the entities as follows:

public class UserTest : DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<HappyUser> HappyUsers { get; set; }


    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<HappyUser>().Map(m =>
        {
            m.MapInheritedProperties();
            m.ToTable("HappyUser");
        });
    }
}

表已正确生成,但是当我查询表时,EF会在User和HappyUser表上生成UNION.查询如下:

The tables are generated correctly, but when I query the tables, EF generates a UNION on the User and HappyUser table. The query is as follows:

        UserTest db = new UserTest();

        var users = from u in db.Users
                    select u;

        var happyUsers = from u in db.Users.OfType<HappyUser>()
                         select u;

用于用户的SQL会生成一个UNION.这不是我期望或想要的.我只想从用户"表中检索行.

The SQL for the Users generates a UNION. This is not what I expect or want. I'd like to simply retrieve the rows from the Users table.

SELECT 
CASE WHEN ([UnionAll1].[C2] = 1) THEN '0X' ELSE '0X0X' END AS [C1], 
[UnionAll1].[Id] AS [C2], 
[UnionAll1].[Name] AS [C3], 
CASE WHEN ([UnionAll1].[C2] = 1) THEN CAST(NULL AS bit) ELSE [UnionAll1].[C1] END AS [C4]
FROM  (SELECT 
 [Extent1].[Id] AS [Id], 
 [Extent1].[Name] AS [Name], 
 CAST(NULL AS bit) AS [C1], 
 cast(1 as bit) AS [C2]
 FROM [dbo].[User] AS [Extent1]
UNION ALL
 SELECT 
 [Extent2].[Id] AS [Id], 
 [Extent2].[Name] AS [Name], 
 [Extent2].[IsHappy] AS [IsHappy], 
 cast(0 as bit) AS [C1]
 FROM [dbo].[HappyUser] AS [Extent2]) AS [UnionAll1]

HappyUsers的SQL可以正常工作.

The SQL for the HappyUsers works as expected.

SELECT 
'0X0X' AS [C1], 
[Extent1].[Id] AS [Id], 
[Extent1].[Name] AS [Name], 
[Extent1].[IsHappy] AS [IsHappy]
FROM [dbo].[HappyUser] AS [Extent1]

有什么想法我做错了吗?还是这是EF的缺陷?

Any ideas what I am doing wrong? Or is this a defect in EF?

推荐答案

HappyUsers 用户.因此,db.Users 应该返回两者. EF在这里是正确的.

HappyUsers are Users. Hence, db.Users should return both. The EF is correct, here.

但是,EF确实有一个局限性:没有办法(无论如何在L2E中)仅返回 种类型的结果.由于Liskov Substitution校长,您通常不希望这样做.但是,如果您这样做,

However, the EF does have a limitation: There is no way to (in L2E, anyway) return results of only one type. Due to the Liskov Substitution Principal, you don't generally want to do this. But if you do, you can do it in ESQL, and there are (somewhat tedious) workarounds for L2E.

底线:如果您发现自己想要这样做,请重新考虑您的设计.在这种情况下,继承可能不是正确的关系.

Bottom line: If you find yourself wanting to do this, rethink your design. Inheritance is probably not the right relationship in this case.

这篇关于EF Linq到实体查询以生成TPC CTP5代码优先实体的UNION的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆