首先,当我从我想要的模型中检索一个(或多个)资产时
获取与其关联的各个国家/地区。那时我会
希望能够将国家列表绑定到 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();
}
第二个选项没问题(从 SQL 的角度不确定它是否比第一个更好)因为AssetId 是主键,所以只能有一个资产。对于按其他标准进行查询 - 例如Asset.Name == "XYZ" - 您可以期望多个资产,我更喜欢第一个选项。第二次您必须将Select 替换为SelectMany,将SingleOrDefault 替换为ToList,并使用Distinct 过滤掉可能的重复国家/地区。 SQL 可能会更复杂。
最后,我希望能够更新给定的国家/地区列表
资产。
这比较棘手,因为您需要处理以下情况:1) 国家/地区已添加到资产中,2) 国家/地区已从资产中删除,3) 国家/地区已与资产相关。
假设您有一个国家/地区 ID 列表 (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% 确定后面的代码是否能正常工作。