有关ADO.NET实体框架的问题,.NET Framework的对象关系映射(ORM)工具。如果适用,请添加特定于版本的标记。不要将此标记用于Entity-Framework核心问题。请改用entity-framework-core。
创建迁移时,如何防止 Entity Framework Core 7 将外键字段添加到引用同一类的某个类?
感谢您阅读本文。我对 Entity Framework Core 有点陌生,我正在尝试使用代码优先原则来创建应该创建数据库的迁移。 但我偶然发现了一些 unex...
CS1061“collectioncollectionbuilder<products, orderproducts>”不包含“hasforeignkey”的定义并且没有可访问的扩展
cs1061“collectioncollectionbuilder”不包含“hasforeignkey”的定义,并且没有可访问的扩展方法“hasforeignkey”接受第一个参数...
我有以下疑问。在代码中它是 Signup.Effort.Parent var user = 等待 context.AppUsers .include(用户 => 用户.以下!) .ThenInclude(org => org.News) .
我有一个没有键的表,Id 作为唯一不可空的列,我必须写入它,所以我必须在我的代码上定义键,选择可能用作键的列。 [表("
EF Core 7.0.4 如何获取对象 Blazor Server 的所有父级
我试图让所有的父母与一个对象相关联。有些对象有父对象,而其他对象可能没有。我正在使用这些数据来创建面包屑。 文件夹.cs { 公共福尔...
Parallel.ForEach 和 SQL 批量插入 20 个
我正在 Parallel.ForEach 语句中编写一些代码。每个线程都应该做一些工作,然后将结果插入列表中。当列表达到 %20 时,它应该插入项目...
如何将实体框架日期转换为不带时间部分的 SQL Server 日期
我有一个日期值,如“2012/01/01 12:36:55”,我想从中过滤 SQL Server 日期值,如“2012/01/01” 我可以在 SQL Server 中转换('2012/01/01 12:36:55', date, 102) 以获得 '2012/01/...
公开课活动 { [钥匙] [数据库生成(数据库生成选项.Identity)] 公共 int Id { 得到;放; } 公共 Guid GuidId { 获取;放; } 公众参观...
我正在使用 dotnet 6 和 GraphQL 7。我仅在一个字段中遇到一些问题。仅当应用程序部署在集群(kubernetes)中时才会出现该错误,而不会在本地部署时出现该错误。所以看起来像
实体框架 - 对象“PK_AspNetUserTokens”依赖于列“UserId”
我在VS 2017(版本15.5)中创建了一个新的ASP.NET Core 2 MVC项目,将用户id类型从字符串更改为Guid(还将ApplicationUser类名更改为User),添加我的模型,然后 添加-Migra...
我使用 EF6 在数据库中存储报表类的实例。数据库已包含数据。假设我想添加要报告的属性, 公开课报告{ // ... 之前的一些
创建新项目时在 Visual Studio 中找不到控制台应用程序 (.NET Core) 模板
在实体框架文档中,提到在创建新项目时选择带有 C# 标签的控制台应用程序 (.NET Core)(在此处)。 但是,我在 Visual Studio 2022 中找不到这样的模板。
UnitOfWork 和 Repository 模式概念问题和最佳实践
我在卡片实体上编写了一个存储库: 公共类 CardRepository :存储库、ICardRepository { 公共 CardRepository(EntityContext 上下文):基础(上下文) { } 公共异步任务
公开课学生 { 公共 int 学生 ID; 公共字符串学生姓名; 公共 int 课程 ID; 公共虚拟课程 Courses { get;放; } } 公开课课程 { 公共法庭...
任何人都可以解释这种行为,以便我将来可以管理它吗? 我有一个带有许多包含语句的查询(定义为 IQueryable)。我正在使用 SQL Server 的实体框架
我有一个 postgres 数据库,我首先使用 ef 来控制我的迁移代码。 我目前有这个表/类。 公开课通知 { [钥匙] 公共 Guid Id { 获取;放; } = Guid.NewGu...
ToArrayAsync() 抛出“源 IQueryable 未实现 IAsyncEnumerable”
我在 ASP.NET Core 上有一个 MVC 项目,我的问题与 IQueryable 和异步有关。我在 IQueryable 中编写了以下搜索方法: 私有 IQueryable 我在 ASP.NET Core 上有一个 MVC 项目,我的问题与 IQueryable 和异步有关。我在IQueryable<T>中写了以下搜索方法: private IQueryable<InternalOrderInfo> WhereSearchTokens(IQueryable<InternalOrderInfo> query, SearchToken[] searchTokens) { if (searchTokens.Length == 0) { return query; } var results = new List<InternalOrderInfo>(); foreach (var searchToken in searchTokens) { //search logic, intermediate results are being added to `results` using `AddRange()` } return results.Count != 0 ? results.Distinct().AsQueryable() : query; } 我在方法中称之为ExecuteAsync(): public async Task<GetAllInternalOrderInfoResponse> ExecuteAsync(GetAllInternalOrderInfoRequest request) { //rest of the code if (searchTokens != null && searchTokens.Any()) { allInternalOrderInfo = WhereSearchTokens(allInternalOrderInfo, searchTokens); } var orders = await allInternalOrderInfo.Skip(offset).Take(limit).ToArrayAsync(); //rest of the code } 当我测试这个时,我在调用 ToArrayAsync() 的地方收到 InvalidOperationException 源 IQueryable 没有实现 IAsyncEnumerable。只有实现 IAsyncEnumerable 的源才能用于实体框架异步操作。 我已将 ToArrayAsync() 更改为 ToListAsync() 但没有任何改变。我已经搜索这个问题一段时间了,但已解决的问题主要与 DbContext 和实体创建有关。该项目没有安装 EntityFramework,由于应用程序架构的原因,最好不要安装。希望有人知道在我的情况下该怎么做。 我发现我必须做更多的工作才能让事情顺利进行: namespace TestDoubles { using Microsoft.EntityFrameworkCore.Query.Internal; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; public static class AsyncQueryable { /// <summary> /// Returns the input typed as IQueryable that can be queried asynchronously /// </summary> /// <typeparam name="TEntity">The item type</typeparam> /// <param name="source">The input</param> public static IQueryable<TEntity> AsAsyncQueryable<TEntity>(this IEnumerable<TEntity> source) => new AsyncQueryable<TEntity>(source ?? throw new ArgumentNullException(nameof(source))); } public class AsyncQueryable<TEntity> : EnumerableQuery<TEntity>, IAsyncEnumerable<TEntity>, IQueryable<TEntity> { public AsyncQueryable(IEnumerable<TEntity> enumerable) : base(enumerable) { } public AsyncQueryable(Expression expression) : base(expression) { } public IAsyncEnumerator<TEntity> GetEnumerator() => new AsyncEnumerator(this.AsEnumerable().GetEnumerator()); public IAsyncEnumerator<TEntity> GetAsyncEnumerator(CancellationToken cancellationToken = default) => new AsyncEnumerator(this.AsEnumerable().GetEnumerator()); IQueryProvider IQueryable.Provider => new AsyncQueryProvider(this); class AsyncEnumerator : IAsyncEnumerator<TEntity> { private readonly IEnumerator<TEntity> inner; public AsyncEnumerator(IEnumerator<TEntity> inner) => this.inner = inner; public void Dispose() => inner.Dispose(); public TEntity Current => inner.Current; public ValueTask<bool> MoveNextAsync() => new ValueTask<bool>(inner.MoveNext()); #pragma warning disable CS1998 // Nothing to await public async ValueTask DisposeAsync() => inner.Dispose(); #pragma warning restore CS1998 } class AsyncQueryProvider : IAsyncQueryProvider { private readonly IQueryProvider inner; internal AsyncQueryProvider(IQueryProvider inner) => this.inner = inner; public IQueryable CreateQuery(Expression expression) => new AsyncQueryable<TEntity>(expression); public IQueryable<TElement> CreateQuery<TElement>(Expression expression) => new AsyncQueryable<TElement>(expression); public object Execute(Expression expression) => inner.Execute(expression); public TResult Execute<TResult>(Expression expression) => inner.Execute<TResult>(expression); public IAsyncEnumerable<TResult> ExecuteAsync<TResult>(Expression expression) => new AsyncQueryable<TResult>(expression); TResult IAsyncQueryProvider.ExecuteAsync<TResult>(Expression expression, CancellationToken cancellationToken) => Execute<TResult>(expression); } } } 这使我能够编写这样的测试: [TestCase("", 3, 5)] [TestCase("100", 2, 4)] public async Task GetOrderStatusCounts_ReturnsCorrectNumberOfRecords(string query, int expectedCount, int expectedStatusProductionCount) { // omitted CreateOrder helper function const int productionStatus = 6; const int firstOtherStatus = 5; const int otherOtherStatus = 7; var items = new[] { CreateOrder(1, "100000", firstOtherStatus, 1), CreateOrder(2, "100000", firstOtherStatus, 4), CreateOrder(3, "100000", productionStatus, 4), CreateOrder(4, "100001", productionStatus, 4), CreateOrder(5, "100100", productionStatus, 4), CreateOrder(6, "200000", otherOtherStatus, 4), CreateOrder(7, "200001", productionStatus, 4), CreateOrder(8, "200100", productionStatus, 4) }.AsAsyncQueryable(); // this is where the magic happens var mocker = new AutoMocker(); // IRepository implementation is also generic and calls DBCntext // for easier testing mocker.GetMock<IRepository<Order>>() .Setup(m => m.BaseQuery() .Returns(items); // the base query is extended in the system under test. // that's the behavior I'm testing here var sut = mocker.CreateInstance<OrderService>(); var counts = await sut.GetOrderStatusCountsAsync(4, query); counts.Should().HaveCount(expectedCount); counts[OrderStatus.Production].Should().Be(expectedStatusProductionCount); } 我编写了一个 ICollection 扩展 AsAsyncQueryable,我在测试中使用它 using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; namespace Whatevaaaaaaaa { public static class ICollectionExtensions { public static IQueryable<T> AsAsyncQueryable<T>(this ICollection<T> source) => new AsyncQueryable<T>(source.AsQueryable()); } internal class AsyncQueryable<T> : IAsyncEnumerable<T>, IQueryable<T> { private IQueryable<T> Source; public AsyncQueryable(IQueryable<T> source) { Source = source; } public Type ElementType => typeof(T); public Expression Expression => Source.Expression; public IQueryProvider Provider => new AsyncQueryProvider<T>(Source.Provider); public IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default) { return new AsyncEnumeratorWrapper<T>(Source.GetEnumerator()); } public IEnumerator<T> GetEnumerator() => Source.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } internal class AsyncQueryProvider<T> : IQueryProvider { private readonly IQueryProvider Source; public AsyncQueryProvider(IQueryProvider source) { Source = source; } public IQueryable CreateQuery(Expression expression) => Source.CreateQuery(expression); public IQueryable<TElement> CreateQuery<TElement>(Expression expression) => new AsyncQueryable<TElement>(Source.CreateQuery<TElement>(expression)); public object Execute(Expression expression) => Execute<T>(expression); public TResult Execute<TResult>(Expression expression) => Source.Execute<TResult>(expression); } internal class AsyncEnumeratorWrapper<T> : IAsyncEnumerator<T> { private readonly IEnumerator<T> Source; public AsyncEnumeratorWrapper(IEnumerator<T> source) { Source = source; } public T Current => Source.Current; public ValueTask DisposeAsync() { return new ValueTask(Task.CompletedTask); } public ValueTask<bool> MoveNextAsync() { return new ValueTask<bool>(Source.MoveNext()); } } } 如果您不打算更改设计 - 您有多种选择: 1) 将 AsQueryable 更改为另一个返回 IQueryable 的方法,该方法也实现了 IDbAsyncEnumerable。例如,您可以扩展 EnumerableQuery (由 AsQueryable 返回): public class AsyncEnumerableQuery<T> : EnumerableQuery<T>, IDbAsyncEnumerable<T> { public AsyncEnumerableQuery(IEnumerable<T> enumerable) : base(enumerable) { } public AsyncEnumerableQuery(Expression expression) : base(expression) { } public IDbAsyncEnumerator<T> GetAsyncEnumerator() { return new InMemoryDbAsyncEnumerator<T>(((IEnumerable<T>) this).GetEnumerator()); } IDbAsyncEnumerator IDbAsyncEnumerable.GetAsyncEnumerator() { return GetAsyncEnumerator(); } private class InMemoryDbAsyncEnumerator<T> : IDbAsyncEnumerator<T> { private readonly IEnumerator<T> _enumerator; public InMemoryDbAsyncEnumerator(IEnumerator<T> enumerator) { _enumerator = enumerator; } public void Dispose() { } public Task<bool> MoveNextAsync(CancellationToken cancellationToken) { return Task.FromResult(_enumerator.MoveNext()); } public T Current => _enumerator.Current; object IDbAsyncEnumerator.Current => Current; } } 然后你改变 results.Distinct().AsQueryable() 到 new AsyncEnumerableQuery<InternalOrderInfo>(results.Distinct()) 之后,ToArrayAsync将不再抛出异常(显然你可以像AsQueryable一样创建自己的扩展方法)。 2)更改ToArrayAsync部分: public static class EfExtensions { public static Task<TSource[]> ToArrayAsyncSafe<TSource>(this IQueryable<TSource> source) { if (source == null) throw new ArgumentNullException(nameof(source)); if (!(source is IDbAsyncEnumerable<TSource>)) return Task.FromResult(source.ToArray()); return source.ToArrayAsync(); } } 并使用 ToArrayAsyncSafe 代替 ToArrayAsync,如果 IQueryable 不是 IDbAsyncEnumerable,它将回退到同步枚举。在您的情况下,只有当查询实际上是内存中列表而不是查询时才会发生这种情况,因此异步执行无论如何都是没有意义的。 对于 EF Core: public static class QueryableExtensions { public static IQueryable<T> AsAsyncQueryable<T>(this IEnumerable<T> input) { return new NotInDbSet<T>( input ); } } public class NotInDbSet< T > : IQueryable<T>, IAsyncEnumerable< T >, IEnumerable< T >, IEnumerable { private readonly List< T > _innerCollection; public NotInDbSet( IEnumerable< T > innerCollection ) { _innerCollection = innerCollection.ToList(); } public IAsyncEnumerator< T > GetAsyncEnumerator( CancellationToken cancellationToken = new CancellationToken() ) { return new AsyncEnumerator( GetEnumerator() ); } public IEnumerator< T > GetEnumerator() { return _innerCollection.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public class AsyncEnumerator : IAsyncEnumerator< T > { private readonly IEnumerator< T > _enumerator; public AsyncEnumerator( IEnumerator< T > enumerator ) { _enumerator = enumerator; } public ValueTask DisposeAsync() { return new ValueTask(); } public ValueTask< bool > MoveNextAsync() { return new ValueTask< bool >( _enumerator.MoveNext() ); } public T Current => _enumerator.Current; } public Type ElementType => typeof( T ); public Expression Expression => Expression.Empty(); public IQueryProvider Provider => new EnumerableQuery<T>( Expression ); } 对于 EFCore 有点晚了,但对于其他希望解决此类问题的人来说,可能的解决方案之一是更改代码以这种方式使用 Task.FromResult() 方法: var result= await allInternalOrderInfo.Skip(offset).Take(limit); var orders = await Task.FromResult(result.ToArray()); AsQueryable()不会将result列表转换为实体框架IQueryable。正如错误所述,与 IQueryable 一起使用的 ToArrayAsync() 应该实现 IAsyncEnumerable,这不是 AsQueryable 将返回的内容。 您可以在此处阅读有关 AsQueryable 在可枚举上的使用的更多信息。 正如 @Titian Cernicova-Dragomir 所指出的,异常意味着 List<InternalOrderInfo> 没有实现 IAsyncEnumerable 但这里有一个逻辑/设计错误。如果您的方法适用于 IQueryable 并返回 IQueryable,则它应该像 IQueryable 一样使用它,而不是像假设集合位于应用程序内存中的 IEnumarable 那样。您确实需要详细了解 IQueryable 和 IEnumarable 之间的区别以及应该从该方法返回什么。一个好的开始点是阅读答案这里和这里 因此,由于您已经在 WhereSearchTokens 方法中甚至之前从数据库中获取了结果,因此没有理由对数据库进行异步请求,这将由 ToArrayAsync 完成并返回 IQueryable。 您有两个选择: 1)如果您的InternalOrderInfo集合在WhereSearchTokens之前从数据库获取到内存中,则使您的所有操作处于同步模式,即调用ToArray而不是ToArrayAsync,并从两者返回IEnumerable而不是Taks<IQueryable> WhereSearchTokens 和 ExecuteAsync。 2)如果您的InternalOrderInfo集合是在WhereSearchTokens内获取的,并且您想要对数据库执行异步请求,则只需在//search logic, intermediate results are being added to results using AddRange()中的某个位置调用异步EF API,然后再次返回Taks<IEnumerable>而不是Taks<IQueryable>来自WhereSearchTokens 错误消息: System.InvalidOperationException:源“IQueryable”未实现“IAsyncEnumerable”。只有实现“IAsyncEnumerable”的源才能用于实体框架异步操作。 对于我的情况,解决方案:当您模拟 dbContext 并将数据从mockSet传递到上下文时,将 .Returns 更改为 .ReturnsDbSet 示例: var mockContext = new Mock<IWebApiDbContext>(); mockContext.Setup(m => m.User).ReturnsDbSet(mockSet.Object); 完整代码模拟数据库: var mockSet = new Mock<DbSet<User>>(); mockSet.As<IDbAsyncEnumerable<User>>() .Setup(m => m.GetAsyncEnumerator()) .Returns(new TestDbAsyncEnumerator<User>(data.GetEnumerator())); mockSet.As<IQueryable<User>>() .Setup(m => m.Provider) .Returns(new TestDbAsyncQueryProvider<User>(data.Provider)); mockSet.As<IQueryable<User>>().Setup(m => m.Expression).Returns(data.Expression); mockSet.As<IQueryable<User>>().Setup(m => m.ElementType).Returns(data.ElementType); mockSet.As<IQueryable<User>>().Setup(m => m.GetEnumerator()).Returns(() => data.GetEnumerator()); var mockContext = new Mock<IWebApiDbContext>(); mockContext.Setup(m => m.User).ReturnsDbSet(mockSet.Object); 最好使用 IAsyncEnumerable<T> 和 IQueryable<T> 来实现集合,而不是创建自己的 ToListAsync 扩展。 您无法在库中应用扩展。 对于 EF Core 5 及更高版本,请检查此实现和测试。 简短版: public sealed class FixedQuery<T> : IAsyncEnumerable<T>, IQueryable<T> { public static readonly IQueryable<T> Empty = Create(ArraySegment<T>.Empty); public static IQueryable<T> Create(params T[] items) { return Create((IEnumerable<T>)items); } public static IQueryable<T> Create(IEnumerable<T> items) { return new FixedQuery<T>(items ?? ArraySegment<T>.Empty).AsQueryable(); } private readonly IQueryable<T> _items; private FixedQuery(IEnumerable<T> items) { _items = (items ?? throw new ArgumentNullException(nameof(items))).AsQueryable(); } #pragma warning disable CS1998 public async IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default) #pragma warning restore CS1998 { foreach (var item in _items) { yield return item; } } public IEnumerator<T> GetEnumerator() { return _items.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public Type ElementType => _items.ElementType; public Expression Expression => _items.Expression; public IQueryProvider Provider => _items.Provider; } 我有同样的错误消息。我知道你的问题表明你不想安装实体框架,但就我而言,其他读者提出这个问题并且没有类似的约束,改变 using System.Data.Entity; 到 using Microsoft.EntityFrameworkCore; 为我工作。 使用此扩展MockQueryable //1 - create a List<T> with test items var users = new List<UserEntity>() { new UserEntity{LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012")}, ... }; //2 - build mock by extension var mock = users.BuildMock(); //3 - setup the mock as Queryable for Moq _userRepository.Setup(x => x.GetQueryable()).Returns(mock); //3 - setup the mock as Queryable for NSubstitute _userRepository.GetQueryable().Returns(mock); //3 - setup the mock as Queryable for FakeItEasy A.CallTo(() => userRepository.GetQueryable()).Returns(mock);
使用数据库优先方法,我已将两个模式导入到我的项目中(没有将连接信息保存到 app.config 文件中)到两个不同的文件夹中:AModel/AModel.edmx 和 BModel/...
类字段类型 { 字符串 ID {获取;放;} 字符串数据类型 {get;set;} } 类字段 { int fId{获取;设置;} 字符串 fName{get;set;} FieldType fType{获取;设置;} 字符串数据; } 班级
当我尝试在 Children 表中插入新项目时,EF Core 中的主键重复
当我在子表中插入一条新记录时,它给我一个错误,说由于主键问题,我无法执行该操作,即当我与父表进行关联时...