gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 08:35:38 26 4
gpt4 key购买 nike

我正在使用 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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com