首先,當我從模型中檢索資產(或資產)時,我想要 獲取與其關聯的相應國家/地區。然後我會 喜歡能夠將國家列表綁定到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