我是EF的新手,并且上面有以下实体模型,其中包含资产和国家/地区。资产可以属于许多国家/地区,因此与国家/地区具有多对多关系(数据库中有一个连接表,两个字段都作为主键)。
我希望能够做到以下几点:
首先,当我从模型中检索资产(或资产)时,我希望获得与其关联的各个国家/地区。然后,我希望能够将国家/地区列表绑定到IEnumerable。以这种方式检索国家为我提供了一个国家对象的EntityCollection,它具有ToList()的扩展方法。因此不确定如果我正沿着正确的大道走下去。这是我的GetAll方法:
public IEnumerable<Asset> GetAll()
{
using (var context = CreateAssetContext())
{
var assetEntities = context.Assets.Include("Countries").ToList();
return AssetMapper.FromEntityObjects(assetEntities);
}
}
其次,我希望能够选择AssetId ==某个值的国家/地区列表。
最后,我希望能够更新给定资产的国家/地区列表。
非常感谢。
答案 0 :(得分:6)
首先,当我从我想要的模型中检索资产(或资产)时 获得与其相关联的各个国家/地区。那我会的 喜欢能够将国家/地区列表绑定到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"
- 您可以期待多个资产我更喜欢第一个选项。对于第二个,您必须按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%肯定。
答案 1 :(得分:0)
具体问题是什么?你不能那样做吗?
是否要选择资产中的国家/地区或拥有特定资产的国家/地区?
更新其简单,只需更改内容,然后context.SaveChanges()
将提交到数据库。