Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# EF6加载相关实体的单个属性_C#_Entity Framework - Fatal编程技术网

C# EF6加载相关实体的单个属性

C# EF6加载相关实体的单个属性,c#,entity-framework,C#,Entity Framework,在EF6中,我有一个实体客户,具有指向实体地址的导航属性。地址实体包含属性“城市” 我可以通过以下方式加载地址实体,同时获得所有客户: _dbSet.Customers.Include(customer => customer.Address); 这给了我所有的客户,以及所有的地址属性 当然,这很好,但我只需要从地址表中获取字段“City”,而不需要从持久数据存储(SQL Server)中获取所有地址属性的感觉并不好 我尝试了以下方法: _dbSet.Customers.Include(

在EF6中,我有一个实体客户,具有指向实体地址的导航属性。地址实体包含属性“城市”

我可以通过以下方式加载地址实体,同时获得所有客户:

_dbSet.Customers.Include(customer => customer.Address);
这给了我所有的客户,以及所有的地址属性

当然,这很好,但我只需要从地址表中获取字段“City”,而不需要从持久数据存储(SQL Server)中获取所有地址属性的感觉并不好

我尝试了以下方法:

_dbSet.Customers.Include(customer => customer.Address.City);
…但这给了我一个运行时异常:

An unhandled exception of type 'System.InvalidOperationException' occurred in mscorlib.dll

Additional information: A specified Include path is not valid. The EntityType 'MyModel.Address'does not declare a navigation property with the name 'City'.
我理解这一点,因为城市只是一个字段,而不是与另一个表/实体的关系

但是,有没有其他方法可以实现我想要的,或者即使我只需要城市字段,也只包含整个地址实体是最佳实践呢


我想要的是,我可以使用myCustomer.Address.City,而无需对数据库进行额外查询,但对于示例,当我使用myCustomer.Address.Street时,Street属性不会立即加载,应该从数据库中额外提取…

仅选择所需的属性,EF将只加载所需的属性

var query = _dbSet.Customers.Include(customer => customer.Address);
var data = query.Select(c => new { Customer = c, City = c.Address.City });
如果您真的打算在整个代码库中使用相同的实体,那么您可以使用类似于Stef建议的方法来解决这个问题:

var query = _dbSet.Customers.Include(customer => customer.Address);
var data = query
    .Select(c => new { Customer = c, City = c.Address.City })
    .ToList() //executes the IQueryable, and fetches the Customer and City (only) from the DB
    .ForEach(x => x.Customer.Address = new Address { City = x.City })
    .Select(x => x.Customer)
    .ToList();

我非常赞成DTO,不在整个代码库中使用实体对象,但上面将为您提供一个
Customer
s列表,其中包含
Address
对象,仅填充了
City
字段。显然,我假设您的对象有公共setter,而实体对象通常有公共setter。

谢谢您的建议。我已经考虑过这个选项,但我不想使用匿名类型。例如,当我稍后在数据访问中将您的代码放入一个方法中,并且我想返回这些对象的集合(从您的答案返回var数据),该方法的返回类型应该是什么?使用Stef建议的投影是一个很好的解决方案。如果你不想处理匿名类型,你可以创建一个CustomerSmallInfoDTO,它只包含你所需要的属性。@SlimH2S,更正,这是一个很好的设计。当您使用AutoMapper时,您可以轻松地将实体映射到DTO对象。您还应该将客户映射到代理/DTO,并且不要在整个应用程序中使用该实体。
.Include(Customer=>Customer.Address)
<代码>\u dbSet.Customers.Select(c=>new{Customer=c,City=c.Address.City})就可以了。感谢您的“解决方案”,但更感谢您关于使用自定义DTO而不是实体对象的建议。我认为现在我将在代码库中使用实体对象,但是当需要扩展时,就像上面的例子一样,我将创建一个自定义DTO。