我在兩個實體Media和MediaCollection之間存在多對多的關係。我想檢查某個媒體是否已經存在於一個集合中。我能做到這一點,如下所示:檢查EF4.1中是否存在多對多關係的有效方法
mediaCollection.Media.Any(m => m.id == mediaId)
然而,mediaCollection.Media是一個ICollection的,所以對我來說,這看起來像它必須從數據庫中檢索集合中的每個媒體只是爲了讓這張支票。由於一個集合中可能有很多媒體,這看起來效率很低。我認爲我應該使用IQueryable的方法,但我看不到如何爲多對多關係做到這一點。
如何檢查關係的存在而不檢索整個集合?
編輯
我生成從我的數據庫中的數據EF模型,然後使用內置的VS POCO T4模板來生成我的數據上下文和實體類。我認爲問題是生成的代碼不會返回導航屬性的EntityCollection,而是ObjectSet。 ObjectSet實現IQueryable,但不公開CreateSourceQuery()方法。
這裏是從上下文相關線路的一個精簡版:
public partial class Entities : ObjectContext
{
public const string ConnectionString = "name=Entities";
public const string ContainerName = "Entities";
#region Constructors
public Entities()
: base(ConnectionString, ContainerName)
{
this.ContextOptions.LazyLoadingEnabled = true;
}
public Entities(string connectionString)
: base(connectionString, ContainerName)
{
this.ContextOptions.LazyLoadingEnabled = true;
}
public Entities(EntityConnection connection)
: base(connection, ContainerName)
{
this.ContextOptions.LazyLoadingEnabled = true;
}
#endregion
#region ObjectSet Properties
public ObjectSet<MediaCollection> MediaCollections
{
get { return _mediaCollections ?? (_mediaCollections = CreateObjectSet<MediaCollection>("MediaCollections")); }
}
private ObjectSet<MediaCollection> _mediaCollections;
// snipped many more
#endregion
}
這裏是類爲MediaCollection實體一個精簡版:
public partial class MediaCollection
{
#region Primitive Properties
// snipped
#endregion
#region Navigation Properties
public virtual ICollection<Medium> Media
{
get
{
if (_media == null)
{
var newCollection = new FixupCollection<Medium>();
newCollection.CollectionChanged += FixupMedia;
_media = newCollection;
}
return _media;
}
set
{
if (!ReferenceEquals(_media, value))
{
var previousValue = _media as FixupCollection<Medium>;
if (previousValue != null)
{
previousValue.CollectionChanged -= FixupMedia;
}
_media = value;
var newValue = value as FixupCollection<Medium>;
if (newValue != null)
{
newValue.CollectionChanged += FixupMedia;
}
}
}
}
private ICollection<Medium> _media;
private void FixupMedia(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
{
foreach (Medium item in e.NewItems)
{
if (!item.MediaCollections.Contains(this))
{
item.MediaCollections.Add(this);
}
}
}
if (e.OldItems != null)
{
foreach (Medium item in e.OldItems)
{
if (item.MediaCollections.Contains(this))
{
item.MediaCollections.Remove(this);
}
}
}
}
// snip
#endregion
}
最後,這裏是模板也生成的FixupCollection:
public class FixupCollection<T> : ObservableCollection<T>
{
protected override void ClearItems()
{
new List<T>(this).ForEach(t => Remove(t));
}
protected override void InsertItem(int index, T item)
{
if (!this.Contains(item))
{
base.InsertItem(index, item);
}
}
}
感謝您的幫助。但是我的上下文是使用T4模板自動生成的(右鍵單擊>添加>新項目> ADO.NET POCO實體生成器)。我的對象似乎沒有CreateSourceQuery()方法。 –