entity-framework - 为什么 Entity Framework 5 在同一实体上执行 .ToList() 与 .Count() 时查询不同的表?

标签 entity-framework linq-to-entities entity-framework-5

我正在使用 Entity Framework 使用实体拆分将两个表映射在一起,如概述 herehere .

我发现如果我执行 .ToList()IQueryable<SplitEntity> 上那么结果来自内部联接。但是,如果我采用相同的 IQueryable 并执行 .Count()它将返回完全连接返回的记录数。

这是一个失败的单元测试:

    [TestMethod]
    public void GetCustomerListTest()
    {
        // arrange
        List<Customer> results;
        int count;

        // act
        using (var context = new DataContext())
        {
            results = context.Customers.ToList();
            count = context.Customers.Count();
        }

        // assert
        Assert.IsNotNull(results); // succeeds
        Assert.IsTrue(results.Count > 0); // succeeds. Has correct records from inner join
        Assert.AreEqual(count, results.Count); // This line fails. Has incorrect count from full join.
    }

这让我觉得非常糟糕。我如何获得 .Count()从内部联接返回结果的方法,如 .ToList() ?

更新 - SQL

我对完整与内部联接的看法是错误的。

.ToList() 结果:
    SELECT 
    [Extent1].[CustomerNumber] AS [CustomerNumber], 
    -- ...etc...
    [Extent2].[CustomerName] AS [CustomerName], 
    -- ... etc...
    FROM  [dbo].[CustomerTable1] AS [Extent1]
    INNER JOIN [dbo].[CustomerTable2] AS [Extent2] ON [Extent1].[CustomerNumber] = [Extent2].[CustomerNumber]

.Count() 结果:
SELECT 
[GroupBy1].[A1] AS [C1]
FROM ( SELECT 
    COUNT(1) AS [A1]
    FROM [dbo].[customerTable2] AS [Extent1]
)  AS [GroupBy1]

更新 - DataContext 和实体代码

数据上下文:
public class DataContext : DbContext
    {
        public DataContext() { Database.SetInitializer<DataContext>(null); }

        public DbSet<Customer> Customers { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Configurations.Add(new CustomerMapping());
        }
    }
}

客户映射 (FluentAPI):
public class CustomerMapping : EntityTypeConfiguration<Customer>
{
    public CustomerMapping()
    {
        this.Map( m => {
                    m.Properties( x => new { x.CustomerNumber, /*...etc...*/});
                    m.ToTable("CustomerTable1");
                })
        .Map( m => {
                    m.Properties( x => new { x.CustomerName, /*...etc...*/});
                    m.ToTable("CustomerTable2");
                });
    }
}

客户实体:
public class Customer
{
    [Key]
    public string CustomerNumber { get; set; }

    public string CustomerName { get; set; }
}

最佳答案

如果数据库和所有记录都在CustomerTable1CustomerTable2已由 Entity Framework 和 SaveChanges 创建在您的应用程序代码中调用这种差异不能发生,您可以直接前进和 report this as a bug .

如果您要映射到现有数据库或其他应用程序将记录写入表中,并且您实际上希望不是 CustomerTable1 中的每条记录在CustomerTable2有对应的记录反之亦然,那么实体拆分是数据库架构的错误映射。

显然,差异意味着您可以拥有 Customer s 带有 CustomerNumber (等),但没有 CustomerName (等) - 或者反过来。对此建模的更好方法是一对一关系,其中一侧是必需的,另一侧是可选的。为此,您将需要一个额外的实体和一个导航属性,例如:

[Table("CustomerTable1")]
public class Customer
{
    [Key]
    public string CustomerNumber { get; set; }
    // + other properties belonging to CustomerTable1

    public AdditionalCustomerData AdditionalCustomerData { get; set; }
}

[Table("CustomerTable2")]
public class AdditionalCustomerData
{
    [Key]
    public string CustomerNumber { get; set; }
    public string CustomerName { get; set; }
    // + other properties belonging to CustomerTable2
}

使用此 Fluent API 映射:
public class CustomerMapping : EntityTypeConfiguration<Customer>
{
    public CustomerMapping()
    {
        this.HasOptional(c => c.AdditionalCustomerData)
            .WithRequired()
            .WillCascadeOnDelete(true);
    }
}

关于entity-framework - 为什么 Entity Framework 5 在同一实体上执行 .ToList() 与 .Count() 时查询不同的表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18004090/

相关文章:

c# - Entity Framework : How to set model as Serializable in Entity Framework

c# - EF、AddRange、Collection 被修改;枚举操作可能无法执行

c# - IQueryable<T> 没有获取导航属性

c# - LINQ to Entity Framework 多重连接与多个动态搜索条件

entity-framework - EF 5.0 DbSet Find 方法返回 null

c# - 存储库模式只能与 Entity Framework 一起使用吗?

c# - 转换时输入字符串的格式不正确,将值插入循环内的数据库中

c# - 来自 2 个不同 Entity Framework 的 Linq 连接查询

entity-framework - 存储库模式如何定义 OrderBy

c# - 如何在 Entity Framework 中结合 inner join 和 left join