|
1 | 1 | using System; |
| 2 | +using System.Collections; |
2 | 3 | using System.Collections.Generic; |
3 | 4 | using System.ComponentModel; |
4 | 5 | using System.Linq; |
@@ -622,6 +623,23 @@ public void Shoud_convert_type_changes() |
622 | 623 | // //result.Any(s => s.DestValue > 6).ShouldBeTrue(); |
623 | 624 | //} |
624 | 625 |
|
| 626 | + [Fact] |
| 627 | + public void Should_dispose_enumerator_when_arbitrary_projection_is_enumerated() |
| 628 | + { |
| 629 | + // Arrange |
| 630 | + var mapper = SetupAutoMapper(); |
| 631 | + var source = new NotSingleQueryingEnumerable<Detail>(); |
| 632 | + |
| 633 | + // Act |
| 634 | + source.AsQueryable() |
| 635 | + .UseAsDataSource(mapper).For<DetailDto>() |
| 636 | + .Select(m => m.Name) |
| 637 | + .ToList(); |
| 638 | + |
| 639 | + // Assert |
| 640 | + NotRelationalDataReader.Instance.ShouldBeNull(); |
| 641 | + } |
| 642 | + |
625 | 643 | private static IMapper SetupAutoMapper() |
626 | 644 | { |
627 | 645 | var config = new MapperConfiguration(cfg => |
@@ -825,6 +843,96 @@ public class ResourceDto |
825 | 843 | public string Title { get; set; } |
826 | 844 | public bool HasEditPermission { get; set; } |
827 | 845 | } |
| 846 | + |
| 847 | + public class NotRelationalDataReader : IDisposable |
| 848 | + { |
| 849 | + public static NotRelationalDataReader Instance { get; set; } |
| 850 | + |
| 851 | + public NotRelationalDataReader() |
| 852 | + { |
| 853 | + Instance = this; |
| 854 | + } |
| 855 | + |
| 856 | + public void Dispose() |
| 857 | + { |
| 858 | + Instance = null; |
| 859 | + } |
| 860 | + } |
| 861 | + |
| 862 | + /// <remarks> |
| 863 | + /// Based on <see href="https://github.com/dotnet/efcore/blob/08e5ebd/src/EFCore.Relational/Query/Internal/SingleQueryingEnumerable.cs">Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable<T></see> |
| 864 | + /// for <see cref="Enumerator.MoveNext"/> and <see cref="Enumerator.Dispose"/>. |
| 865 | + /// </remarks> |
| 866 | + public class NotSingleQueryingEnumerable<T> : IQueryable<T>, IQueryProvider |
| 867 | + { |
| 868 | + public Type ElementType => throw new NotImplementedException(); |
| 869 | + |
| 870 | + public Expression Expression => Expression.Constant(this); |
| 871 | + |
| 872 | + public IQueryProvider Provider => this; |
| 873 | + |
| 874 | + public IQueryable CreateQuery(Expression expression) |
| 875 | + { |
| 876 | + return this; |
| 877 | + } |
| 878 | + |
| 879 | + public IQueryable<TElement> CreateQuery<TElement>(Expression expression) |
| 880 | + { |
| 881 | + throw new NotImplementedException(); |
| 882 | + } |
| 883 | + |
| 884 | + public object Execute(Expression expression) |
| 885 | + { |
| 886 | + throw new NotImplementedException(); |
| 887 | + } |
| 888 | + |
| 889 | + public TResult Execute<TResult>(Expression expression) |
| 890 | + { |
| 891 | + throw new NotImplementedException(); |
| 892 | + } |
| 893 | + |
| 894 | + public IEnumerator<T> GetEnumerator() |
| 895 | + { |
| 896 | + throw new NotImplementedException(); |
| 897 | + } |
| 898 | + |
| 899 | + IEnumerator IEnumerable.GetEnumerator() |
| 900 | + { |
| 901 | + return new Enumerator(); |
| 902 | + } |
| 903 | + |
| 904 | + private sealed class Enumerator : IEnumerator<T> |
| 905 | + { |
| 906 | + private NotRelationalDataReader _dataReader; |
| 907 | + |
| 908 | + public T Current => throw new NotImplementedException(); |
| 909 | + |
| 910 | + object IEnumerator.Current => throw new NotImplementedException(); |
| 911 | + |
| 912 | + public void Dispose() |
| 913 | + { |
| 914 | + if (_dataReader is not null) |
| 915 | + { |
| 916 | + _dataReader.Dispose(); |
| 917 | + _dataReader = null; |
| 918 | + } |
| 919 | + } |
| 920 | + |
| 921 | + public bool MoveNext() |
| 922 | + { |
| 923 | + if (_dataReader == null) |
| 924 | + { |
| 925 | + _dataReader = new NotRelationalDataReader(); |
| 926 | + } |
| 927 | + return false; |
| 928 | + } |
| 929 | + |
| 930 | + public void Reset() |
| 931 | + { |
| 932 | + throw new NotImplementedException(); |
| 933 | + } |
| 934 | + } |
| 935 | + } |
828 | 936 | } |
829 | 937 |
|
830 | 938 |
|
0 commit comments