diff --git a/src/EFCore/ChangeTracking/LocalView.cs b/src/EFCore/ChangeTracking/LocalView.cs
index 30ed6916834..baf3e6afd8c 100644
--- a/src/EFCore/ChangeTracking/LocalView.cs
+++ b/src/EFCore/ChangeTracking/LocalView.cs
@@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
@@ -46,7 +47,7 @@ namespace Microsoft.EntityFrameworkCore.ChangeTracking
///
///
/// The type of the entity in the local view.
- public class LocalView : ICollection, INotifyCollectionChanged, INotifyPropertyChanged, INotifyPropertyChanging
+ public class LocalView : ICollection, INotifyCollectionChanged, INotifyPropertyChanged, INotifyPropertyChanging, IListSource
where TEntity : class
{
private ObservableBackedBindingList _bindingList;
@@ -443,5 +444,26 @@ private void OnCollectionChanged(NotifyCollectionChangedAction action, object it
/// The binding list.
public virtual BindingList ToBindingList()
=> _bindingList ?? (_bindingList = new ObservableBackedBindingList(ToObservableCollection()));
+
+ ///
+ ///
+ /// This method is called by data binding frameworks when attempting to data bind
+ /// directly to a .
+ ///
+ ///
+ /// This implementation always throws an exception as
+ /// does not maintain an ordered list with indexes. Instead call
+ /// for WPF binding, or for WinForms.
+ ///
+ ///
+ /// Always thrown.
+ /// Never returns, always throws an exception.
+ IList IListSource.GetList() => throw new NotSupportedException(CoreStrings.DataBindingWithIListSource);
+
+ ///
+ /// Gets a value indicating whether the collection is a collection of System.Collections.IList objects.
+ /// Always returns false.
+ ///
+ bool IListSource.ContainsListCollection => false;
}
}
diff --git a/src/EFCore/Query/Internal/EntityQueryable`.cs b/src/EFCore/Query/Internal/EntityQueryable`.cs
index b43033e2a0c..cc7db187b61 100644
--- a/src/EFCore/Query/Internal/EntityQueryable`.cs
+++ b/src/EFCore/Query/Internal/EntityQueryable`.cs
@@ -1,10 +1,14 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+using System;
+using System.Collections;
using System.Collections.Generic;
+using System.ComponentModel;
using System.Linq.Expressions;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Utilities;
+using Microsoft.EntityFrameworkCore.Internal;
using Remotion.Linq;
namespace Microsoft.EntityFrameworkCore.Query.Internal
@@ -13,7 +17,7 @@ namespace Microsoft.EntityFrameworkCore.Query.Internal
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
///
- public class EntityQueryable : QueryableBase, IAsyncEnumerable, IDetachableContext
+ public class EntityQueryable : QueryableBase, IAsyncEnumerable, IDetachableContext, IListSource
{
///
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
@@ -35,10 +39,33 @@ public EntityQueryable([NotNull] IAsyncQueryProvider provider, [NotNull] Express
{
}
+ ///
+ /// This API supports the Entity Framework Core infrastructure and is not intended to be used
+ /// directly from your code. This API may change or be removed in future releases.
+ ///
IAsyncEnumerator IAsyncEnumerable.GetEnumerator()
=> ((IAsyncQueryProvider)Provider).ExecuteAsync(Expression).GetEnumerator();
+ ///
+ /// This API supports the Entity Framework Core infrastructure and is not intended to be used
+ /// directly from your code. This API may change or be removed in future releases.
+ ///
IDetachableContext IDetachableContext.DetachContext()
=> new EntityQueryable(NullAsyncQueryProvider.Instance);
+
+ ///
+ /// This API supports the Entity Framework Core infrastructure and is not intended to be used
+ /// directly from your code. This API may change or be removed in future releases.
+ ///
+ IList IListSource.GetList()
+ {
+ throw new NotSupportedException(CoreStrings.DataBindingWithIListSource);
+ }
+
+ ///
+ /// This API supports the Entity Framework Core infrastructure and is not intended to be used
+ /// directly from your code. This API may change or be removed in future releases.
+ ///
+ bool IListSource.ContainsListCollection => false;
}
}
diff --git a/test/EFCore.Tests/DbSetTest.cs b/test/EFCore.Tests/DbSetTest.cs
index 8610c889e64..2cb7f4e311f 100644
--- a/test/EFCore.Tests/DbSetTest.cs
+++ b/test/EFCore.Tests/DbSetTest.cs
@@ -566,6 +566,26 @@ public void Throws_when_using_with_IListSource()
}
}
+ [Fact]
+ public void Throws_when_using_query_with_IListSource()
+ {
+ using (var context = new EarlyLearningCenter())
+ {
+ Assert.Equal(CoreStrings.DataBindingWithIListSource,
+ Assert.Throws(() => ((IListSource)context.Gus.Distinct()).GetList()).Message);
+ }
+ }
+
+ [Fact]
+ public void Throws_when_using_Local_with_IListSource()
+ {
+ using (var context = new EarlyLearningCenter())
+ {
+ Assert.Equal(CoreStrings.DataBindingWithIListSource,
+ Assert.Throws(() => ((IListSource)context.Gus.Local).GetList()).Message);
+ }
+ }
+
private class Category
{
public int Id { get; set; }