首先,当我从模型中检索资产(或资产)时,我想要 获取与其关联的相应国家/地区。然后我会 喜欢能够将国家列表绑定到IEnumerable。
不知道如果我的理解是正确的,但EntityCollection<T>
实现IEnumerable<T>
,所以你没有做什么特别的,你只可以使用Asset.Countries
已装入资产,包括国家之后。
其次,我希望能够选择一个国家的列表,其中AssetId = ==某些值。
using (var context = CreateAssetContext())
{
var countries = context.Countries
.Where(c => c.Assets.Any(a => a.AssetId == givenAssetId))
.ToList();
}
或者:
using (var context = CreateAssetContext())
{
var countries = context.Assets
.Where(a => a.AssetId == givenAssetId)
.Select(a => a.Countries)
.SingleOrDefault();
}
第二个选项是OK(不知道这是不是从SQL观点一批好),因为AssetId
是主键,因此只能有一个资产。对于其他条件的查询 - 例如Asset.Name == "XYZ"
- 您可以预期多个资产,我宁愿选择第一个选项。第二,你必须用SelectMany
和SingleOrDefault
将Select
替换成ToList
,并使用Distinct
来过滤掉可能出现的重复国家。 SQL可能会更复杂。
最后,我希望能够更新给定 资产的国家/地区列表。
这样比较棘手,因为您需要处理以下情况:1)国家已被添加到资产中,2)国家已从资产中删除,3)国家已与资产相关。
假设你有一个国家的IDS(IEnumerable<int> countryIds
)列表,并要涉及这些国家给定的资产:
using (var context = CreateAssetContext())
{
var asset = context.Assets.Include("Countries")
.Where(a => a.AssetId == givenAssetId)
.SingleOrDefault();
if (asset != null)
{
foreach (var country in asset.Countries.ToList())
{
// Check if existing country is one of the countries in id list:
if (!countryIds.Contains(country.Id))
{
// Relationship to Country has been deleted
// Remove from asset's country collection
asset.Countries.Remove(country);
}
}
foreach (var id in countryIds)
{
// Check if country with id is already assigned to asset:
if (!asset.Countries.Any(c => c.CountryId == id))
{
// No:
// Then create "stub" object with id and attach to context
var country = new Country { CountryId = id };
context.Countries.Attach(country);
// Then add to the asset's country collection
asset.Countries.Add(country);
}
// Yes: Do nothing
}
context.SaveChanges();
}
}
编辑
对于第二往返的价格向数据库,你可以使用这个更简单的代码:
using (var context = CreateAssetContext())
{
var asset = context.Assets.Include("Countries")
.Where(a => a.AssetId == givenAssetId)
.SingleOrDefault();
if (asset != null)
{
// second DB roundtrip
var countries = context.Countries
.Where(c => countryIds.Contains(c.CountryId))
.ToList();
asset.Countries = countries;
context.SaveChanges();
}
}
EF的变化检测应该能够识别哪个国家已经从资产的国家列表中添加或删除。如果后面的代码能正常工作,我不是100%确定的。
非常好的Slauma谢谢你的详细解答,我会试一试,让你知道我是怎么做到的。 – Cragly
@Cragly:我已经为第二个问题添加了第二个查询选项。是的,让我特别知道,如果编辑部分中的代码工作(如果你应该测试它):) – Slauma
对不起,延迟但被卡在别的东西!刚刚尝试过两种版本,并且差不多在那里。他们两个人唯一的问题是,当我尝试创建一个新的Country对象来添加到资源时,它的类型不正确。国家实体是一个纯粹的EF对象,但与资产相关的是Assets.Country类型,不会让我添加它。已经有了一些映射,但仍然不能让它玩球。对于导航属性是不同类型的多对多关系,情况如何? – Cragly