标签: dbcontext

每组最高:Take(1)有效,但FirstOrDefault()没有?

我正在使用EF 4.3.1 ...刚刚升级到4.4(问题仍然存在),由EF 4.x DbContext Generator生成的数据库优先POCO实体.我有以下数据库名为'Wiki'(用于创建表和数据的SQL脚本在这里):

作者(ID,姓名)< - 文章(AuthorID,Title,Revision,CreatedUTC,Body)

编辑Wiki文章时,不会更新其记录,而是将新版本作为新记录插入,并使修订计数器递增.在我的数据库中有一位作者"John Doe",它有两篇文章,"文章A"和"文章B",其中文章A有两个版本(1和2),但文章B只有一个版本.

在此输入图像描述

我禁用了延迟加载和代理创建(这里是我使用LINQPad的示例解决方案).我想获得由名字以"John"开头的人创建的文章的最新版本,所以我做了以下查询:

Authors.Where(au => au.Name.StartsWith("John"))
       .Select(au => au.Articles.GroupBy(ar => ar.Title)
                                .Select(g => g.OrderByDescending(ar => ar.Revision)
                                              .FirstOrDefault()))
Run Code Online (Sandbox Code Playgroud)

这会产生错误的结果,并仅检索第一篇文章:

在此输入图像描述

结交查询小的变化,通过更换.FirstOrDefault().Take(1)下面的查询结果:

Authors.Where(au => au.Name.StartsWith("John"))
       .Select(au => au.Articles.GroupBy(ar => ar.Title)
                                .Select(g => g.OrderByDescending(ar => ar.Revision)
                                              .Take(1)))
Run Code Online (Sandbox Code Playgroud)

令人惊讶的是,此查询产生了正确的结果(尽管有更多嵌套):

在此输入图像描述

我假设EF生成略有不同的SQL查询,一个只返回单个文章的最新版本,另一个返回所有文章的最新版本.两个查询生成的丑陋SQL差别不大(比较:针对.FirstOrDefault()的SQL针对.Take (1)的SQL相比,但它们都返回正确的结果:

.FirstOrDefault()

在此输入图像描述

.Take(1) (重新排列列顺序以便于比较)

在此输入图像描述

因此,罪魁祸首不是生成的SQL,而是EF对结果的解释.为什么EF将第一个结果解释为单个Article实例,而将第二个结果解释为两个Article实例?为什么第一个查询返回不正确的结果?

编辑:我已经打开了关于Connect 的错误报告.如果您认为解决此问题很重要,请进行投票.

.net c# entity-framework entity-framework-4.1 dbcontext

9
推荐指数
1
解决办法
5483
查看次数

"..."无法实现接口成员,因为它不是公共的

public interface IDatabaseContext : IDisposable {

    IDbSet<MyEntity1> Entities1 { get; set; }

}

public class MyDbContext : DbContext, IDatabaseContext {

    IDbSet<MyEntity1> Entities1 { get; set; }

}
Run Code Online (Sandbox Code Playgroud)

由于此处描述的错误无法编译:http://msdn.microsoft.com/en-Us/library/bb384253(v = vs.90).aspx

然而,由于界面显然是公开的,所以这没有任何意义.这可能是什么错误?

c# entity-framework dbcontext

9
推荐指数
2
解决办法
1万
查看次数

如何在 EF Core 2.2 中使用支持字段设置只读集合属性

我正在尝试创建一个实体类,它将通过只读属性公开相关集合,如下所示:

public class MyEntity: Entity
{
    public int Id{ get; private set; }
    private IList<RelatedEntity> _relatedEntities = new List<RelatedEntity>();
    public IReadOnlyList<RelatedEntity> RelatedEntities => _relatedEntities.ToList().AsReadOnly();
}
Run Code Online (Sandbox Code Playgroud)

构建器类如下所示:

public void Configure(EntityTypeBuilder<MyEntity> builder)
{
    builder.HasKey(x=>x.Id);
    builder.Property<IReadOnlyList<RelatedEntity>>("RelatedEntities")
        .HasField("_relatedEntities ")
        .UsePropertyAccessMode(PropertyAccessMode.Field);
}
Run Code Online (Sandbox Code Playgroud)

它可以构建,但在运行时崩溃,但有以下例外:

InvalidOperationException:“IList”类型的指定字段“_latedEntities”不能用于“IReadOnlyList”类型的属性“MyEntity.RelatedEntities”。只能使用可从属性类型分配的类型的支持字段。

您能提供一个如何处理这个问题的工作示例吗?

c# dbcontext entity-framework-core

9
推荐指数
3
解决办法
8108
查看次数

EF Core 无跟踪和 Add() 或 Update()

我试图让我的 DbContext 在没有跟踪的情况下工作。

public class MyContext: DbContext
{
    public MyContext() 
    {
        ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

另外,在每次 Add(..) 或 Update(..) 之后,我都会删除对新实体的跟踪:

_context.Users.Add(user);
await _context.SaveChangesAsync();
_context.Entry(user).State = EntityState.Detached;
Run Code Online (Sandbox Code Playgroud)

如果我添加(或更新)一个引用现有实体(意味着已存储在数据库中)的新实体,就会出现问题。

例如:

var section = new Section();
_context.Sections.Add(section);
await _context.SaveChangesAsync();
_context.Entry(section).State = EntityState.Detached;

...

var user = new User
{
   Name = "Alex",
   Section = section
}

_context.Users.Add(user);
await _context.SaveChangesAsync();
Run Code Online (Sandbox Code Playgroud)

结果出现错误:

System.ArgumentException: '已添加具有相同键的项目。钥匙:1'

我怎样才能解决这个问题?

c# entity-framework dbcontext ef-core-3.1

9
推荐指数
2
解决办法
2万
查看次数

EF +通用存储库+加载相关实体:仅显式加载工作

我有两个简单的POCO课程; 我试图MyY通过一个实例获得低于水合物的属性Y.我已经尝试了很多方法来做到这一点,并认为我可能会遗漏一些明显或简单的东西.

public class X
{
     public int Id { get; set;}
     public virtual Y MyY { get; set; }
}

public class Y
{
     public int Id { get; set; }
     // ...
}
Run Code Online (Sandbox Code Playgroud)

我在我DbContext的构造函数的子类中通过这个调用关闭了延迟加载:

Configuration.LazyLoadingEnabled = false;
Run Code Online (Sandbox Code Playgroud)

检索时X我试过了

context.Set<X>.Include("MyY").FirstOrDefault(x => ....);
Run Code Online (Sandbox Code Playgroud)

这没用.我试过了

var result = context.Set<X>.FirstOrDefault(x => ....);
context.Entry(result).Reference("MyY").Load();
Run Code Online (Sandbox Code Playgroud)

哪个有效,但需要两次往返数据库.我试过了

context.Set<X>.Select(x => new { X = x, Y = x.MyY }).FirstOrDefault(x => ...);
Run Code Online (Sandbox Code Playgroud)

这也有效,但"削弱"我的模型(通常投射到一个新类型并不是那么糟糕,但这些EF POCO的"形状"适用于我稍后将通过WCF发送的DTO).

我终于尝试virtual从另一个问题MyY的 …

c# ef-code-first entity-framework-4.1 dbcontext

8
推荐指数
1
解决办法
7038
查看次数

EF和存储库模式 - 在一个控制器中以多个DbContexts结束 - 任何问题(性能,数据完整性)?

我对ASP.NET MVC 3的大部分知识来自阅读Adam Freeman和Steven Senderson撰写的Pro ASP.NET MVC 3 Framework一书.对于我的测试应用程序,我试图非常密切地坚持他们的例子.我正在使用存储库模式加上Ninject和Moq,这意味着单元测试工作得很好(即无需从数据库中提取数据).

在本书中,存储库的使用方式如下:

public class EFDbTestChildRepository
{
    private EFDbContext context = new EFDbContext();

    public IQueryable<TestChild> TestChildren
    {
        get { return context.TestChildren; }
    }

    public void SaveTestChild(TestChild testChild)
    {
        if (testChild.TestChildID == 0)
        {
            context.TestChildren.Add(testChild);
        }
        else
        {
            context.Entry(testChild).State = EntityState.Modified;
        }
        context.SaveChanges();
    }
}
Run Code Online (Sandbox Code Playgroud)

这是与之相关的DbContext:

public class EFDbContext : DbContext
{
    public DbSet<TestParent> TestParents { get; set; }
    public DbSet<TestChild> TestChildren { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

请注意:为了简化这个提取的例子,我在这里省略了接口ITestChildRepository,然后Ninject会使用它.

在其他来源中,我看到了一个更通用的存储库方法,其中一个存储库足以满足整个应用程序的需要.显然在我的情况下,我最终在我的应用程序中列出了相当多的存储库列表 - 基本上我的域模型中的每个实体都有一个.不确定这两种方法的优缺点 - 我只是按照这本书的安全性来做.

最后得到我的问题:每个存储库都有自己的DbContext …

repository-pattern entity-framework-4 asp.net-mvc-3 dbcontext

8
推荐指数
2
解决办法
6721
查看次数

如何在Entity Framework中更新实体的导航属性

在带有Entity Framework的ASP .NET MVC 3中,我有一个域对象,它具有引用其他对象的导航属性,如下所示:

public class Person
{
    public String Name {get;set;}

    public Guid CompanyID{get;set;}

    [ForeignKey(CompanyID)]
    public virtual CompanyType Company{ get; set; }
}
Run Code Online (Sandbox Code Playgroud)

当我创建Person的实例并尝试将其添加到数据库时,DBContext会保留此实体"Person"的缓存并将其发送到数据库.所以稍后在同一个上下文实例的生命周期中,当我尝试访问此实体时,Company字段始终为null,因为导航属性永远不会更新.

有没有办法用数据库中存在的内容更新导航属性?

延迟加载已打开.

entity-framework navigation-properties ef-code-first asp.net-mvc-3 dbcontext

8
推荐指数
1
解决办法
5278
查看次数

不使用SqlParameterCollection时,另一个SqlParameterCollection已包含SqlParameter

我有以下是抛出一个SqlParameter已经被catch中的另一个SqlParameterCollection异常包含.

我觉得奇怪的是,我们无处可创造一个SqlParameterCollection.每次我们创建一个新实例,所以SqlParameter从不使用过多次.另一个奇怪的是,它test包含来自存储过程的正确结果,并将结果返回给调用方法,但是当我再次从第一行3开始执行4时,它决定进入catch块.不在33我期望它发生的位置...如果它帮助我们使用CodeFirst生成工具从ObjectContexta 切换到a DbContext.使用的所有其他数据库交互和存储过程都按预期工作.

1    try
2    {
3        tempMessages = Context.CheckExistingTables(importSession.ImportSessionID).ToList();
4    }
5    catch (Exception e)
6    {
7        this.LogError("Error validating the import file entities", e);
8        tempMessages.Add(new ErrorMessage() { ErrorType = 3, Message = string.Format("Error validating the import file entities: {0}", e.Message) });
9    }
...
20    public IEnumerable<ErrorMessage> CheckExistingTables(Guid? importSessionID)
21    {
22        SqlParameter …
Run Code Online (Sandbox Code Playgroud)

c# asp.net-mvc stored-procedures dbcontext

8
推荐指数
1
解决办法
8866
查看次数

如何使用NSubstitute模拟DbContext然后添加/删除数据

我需要模仿EF的DbContext.我在这里使用这种方法,效果很好.

// mock a DbSet
var mockDbSet = Substitute.For<DbSet<Foo>, IQueryable<Foo>>();
var data = new List<Foo>().AsQueryable();
((IQueryable<Foo>)mockDbSet).Provider.Returns(data.Provider);
((IQueryable<Foo>)mockDbSet).Expression.Returns(data.Expression);
((IQueryable<Foo>)mockDbSet).ElementType.Returns(data.ElementType);
((IQueryable<Foo>)mockDbSet).GetEnumerator().Returns(data.GetEnumerator());
// now add it to a mock DbContext
var mockContext = Substitute.For<MyDbContextClass>();
mockContext.Set<Foo>().Returns(mockDbSet);
Run Code Online (Sandbox Code Playgroud)

然而,在某些测试中,我需要能够调用mockContext.Set<Foo>().Add(someFoo)mockContext.Set<Foo>().Remove(otherFoo),并为潜在的添加/删除逻辑工作.

我试过这个:

mockDbSet.When(x => x.Add(Arg.Any<Foo>())).Do(x => data.Add(x.Arg<Foo>()));
Run Code Online (Sandbox Code Playgroud)

但它抛出了 Collection was modified; enumeration operation may not execute.

那么如何实现添加/删除功能呢?

c# entity-framework nsubstitute dbcontext dbset

8
推荐指数
1
解决办法
3037
查看次数

DbContext.Database.Migrate() 方法在哪里?

我本打算在启动时调用此方法,但它不在任何地方引用:

dbContext.Database.Migrate();
Run Code Online (Sandbox Code Playgroud)

类型DatabaseFacade不包含 的定义,Migrate并且找不到Migrate类型的扩展方法DatabaseFacade(您是否缺少 using 指令或程序集引用?

那么我缺少哪个使用/程序集?

c# dbcontext entity-framework-migrations ef-core-3.0

8
推荐指数
3
解决办法
8100
查看次数