我之前的问题让我再次思考层,存储库,依赖注入和这样的架构.
我的架构现在看起来像这样:
我首先使用EF代码,所以我只创建了POCO类和上下文.这创建了db和model.
级别更高的是业务层类(提供者).我为每个域使用不同的提供程序...比如MemberProvider,RoleProvider,TaskProvider等.我在每个提供程序中创建我的DbContext的新实例.
然后我在我的控制器中实例化这些提供程序,获取数据并将它们发送到Views.
我的初始架构包括存储库,我之所以摆脱它是因为我被告知它只会增加复杂性,所以为什么我不仅仅使用EF.我想这样做..直接从控制器使用EF,但我必须编写测试,它与真正的数据库有点复杂.我不得不假装 - 以某种方式模拟数据.因此,我为每个提供商创建了一个接口,并使列表中的硬编码数据成为假提供者.有了这个,我回到了一些东西,我不知道如何正确地进行.
这些事情开始过于复杂化......许多方法和"模式"......它产生了太多的噪音和无用的代码.
是否有任何SIMPLE和可测试的体系结构用于使用Entity Framework创建和ASP.NET MVC3应用程序?
architecture asp.net-mvc unit-testing entity-framework code-first
我刚刚开始使用Entity框架,我对业务层中通常的类如何适应实体框架创建的实体感到困惑.
使用经典的ADO.NET时,我会有一个名为Customer的类,然后是另一个名为DALCustomer的类来处理数据库交互,在这个结构中,我会把代码放到计算,过滤和删除DAL的实例中.客户在Customer类中保存,更新和删除.
使用Entity Framework,如果您有一个名为Customer的表,Entity框架会创建一个名为Customer的实体,这就是我的困惑开始的地方,这个实体是否消除了业务层中对Customer的需求?因此,实质上通常在业务层中的所有字段和方法都在实体框架生成的实体中?或者,如果一个类仍然存在于名为CustomerBL的业务层中,那么它仍然包含完成计算,过滤所需的业务逻辑所需的字段和方法,并且仍然需要声明处理数据访问的EF DAL实例?
如果应该有一个业务类,在这种情况下是CustomerBL,另外还有一个问题,如果客户实体中创建的字段在CustomerBL中重新创建,或者应该在CustomerBL中声明Customer实体的实例,那么就会有不需要在2个位置声明字段?
我使用Entity Framework数据库优先方法为MVC应用程序生成DbContext/POCO模型.我想避免在我的控制器中依赖DbContext来使我能够根据需要切换到另一个持久性提供程序(例如用于单元测试).
为此,我想使用Castle Windsor IoC容器.我计划将DbContext注册为IUnitOfWork服务并注册一个通用的IRepository服务,我将使用它来访问和使用模型中的聚合根.
我是Windsor的新手,并且无法找到关于在EF中使用它的更多信息,我有几个问题:
asp.net-mvc entity-framework castle-windsor inversion-of-control
我目前正在尝试对通过Entity Framework进行的存储库进行单元测试:
我想要发生的是测试存储库而不实际发送/连接到实际的数据库,我想这样做而不使用任何模拟框架.
目前我的测试是将数据发送到数据库,我想要发生的是测试添加/删除等方法而不将实际数据发送到数据库,因为它仅用于测试.
这是存储库:
namespace AbstractFactory.Repository
{
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
/// <summary>
/// This class serves as the structure of the Author repository using a database
/// </summary>
public class DbAuthorRepository : IRepository<AuthorEntity>
{
private AbstractFactoryPatternEntities context;
public DbAuthorRepository(AbstractFactoryPatternEntities context)
{
this.context = context;
}
/// <summary>
/// Adds the specified author.
/// </summary>
/// <param name="author">The author.</param>
public void Add(AuthorEntity author)
{
context.AuthorEntities.Add(author);
}
/// <summary>
/// Removes the specified author.
/// </summary>
/// <param …Run Code Online (Sandbox Code Playgroud) 说,我有两个实体:
public class Customer
{
public int Id { get; set; }
public int SalesLevel { get; set; }
public string Name { get; set; }
public string City { get; set; }
}
public class Order
{
public int Id { get; set; }
public DateTime DueDate { get; set; }
public string ShippingRemark { get; set; }
public int? CustomerId { get; set; }
public Customer Customer { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
Customer是一个可选(可空)引用Order(可能系统支持"匿名"命令). …
我正在做一个小练习项目来提高我的单元测试技能.我正在使用Entity Framework Code First.
我正在使用FakeDBSet,它适用于简单的实体列表.当返回实体树时,事情并不那么好.特别是不保持双向关系,因为这是实体框架魔术的一部分.
我有两节课:
public class Book
{
public virtual ICollection<Review> Reviews {get; set;}
}
public class Review
{
public virtual Book Book { get; set;}
}
Run Code Online (Sandbox Code Playgroud)
如果我将图书设置为评论,则评论不会添加到图书的评论集中.它在使用EF时会发生,但在我的假版本中却没有.
有没有办法模仿这种行为,还是我不应该依赖EF来实现双向关系?或者嘲笑数据上下文只是浪费时间?
我有一个简单的服务表结构,每个服务都有很多设施.在数据库中,这是一个Service表和一个Facility表,其中Facility表具有对Service表中的行的引用.
在我们的应用程序中,我们有以下LINQ工作:
Services
.Where(s => s.Facilities.Any(f => f.Name == "Sample"))
.GroupBy(s => s.Type)
.Select(g => new { Type = g.Key, Count = g.Count() })
Run Code Online (Sandbox Code Playgroud)
但由于我无法控制的原因,源集在Where调用之前被投射到非实体对象,这样:
Services
.Select(s => new { Id = s.Id, Type = s.Type, Facilities = s.Facilities })
.Where(s => s.Facilities.Any(f => f.Name == "Sample"))
.GroupBy(s => s.Type)
.Select(g => new { Type = g.Key, Count = g.Count() })
Run Code Online (Sandbox Code Playgroud)
但这引发了以下异常,没有内部异常:
EntityCommandCompilationException: The nested query is not supported. Operation1='GroupBy' Operation2='MultiStreamNest'
Where …
有人可以帮我解决这个异常:
测试方法KravmagaTests.Model.Entities.StudentTest.Create_Valid_Student抛出异常:System.NotSupportedException:无法创建类型为"Kravmaga.Models.Account"的常量值.在此上下文中仅支持原始类型(例如Int32,String和Guid').
我运行这个测试方法时得到这个:
[TestMethod]
public void Create_Valid_Student()
{
Student student = new Student()
{
Username = "username",
Firstname = "firstname",
Surname = "surname",
Email = "email@gmail.com",
Password = "password",
};
KravmagaContext context = new KravmagaContext();
context.AddToAccounts(student);
context.Save();
bool exists = context.Accounts.Contains(student); // THIS THROWS EXCEPTION
Assert.IsTrue(exists);
}
Run Code Online (Sandbox Code Playgroud)
非常感谢.
我有一个工厂函数来返回一个DbSet(Of IItemType).实际的返回类型将永远是一个实现IItemType,例如DbSet(Of CategoryType).
我认为在泛型中支持协方差,这种方法可以正常工作,但是当我尝试运行代码时出现异常:
无法转换'System.Data.Entity.DbSet
1[CategoryType]' to type 'System.Data.Entity.DbSet1 [IItemType]' 类型的对象.
我正在实现一个存储库模式.我的主要原因是:
通用存储库与否?
我遇到的问题是我是否应该有一个通用的存储库.一种IQueryable<T> Query()方法将为调用代码提供构造特定查询的手段.这里的问题是这是漏洞抽象 - 实体框架细节现在泄漏到我的客户端代码中.

这种影响单元测试怎么样? 我还能ICustomerRepository用这个实现模拟吗?
这种效果如何影响我的持久层?像Azure存储表或NHibernate.
否则我将不得不实现非常具体的查询方法ICustomerRepository,例如GetIsActiveByFirstName()和GetIsActiveByDistrict().我不喜欢这个,因为我的存储库类将变得拥挤不同的查询方法.该系统有数百种型号,因此可以有数百甚至数千种这样的方法来编写和维护.
entity-framework leaky-abstraction repository-pattern onion-architecture entity-framework-5
最近,我启动了一个用于模拟各种神经网络应用程序的项目。为了处理涉及的大量数据,我已经使用实体框架模型优先方法实现了SQL-Server后端。
另外,我对测试驱动开发(TDD)学科也非常喜欢。但是,为了做到这一点,我需要一个模拟数据库来运行我的测试。经过大量搜索,我发现了商业和开源的多种解决方案。在这一点上,值得注意的是,我是数据库相关主题的新手。因此我选择使用MSDN在内存中模拟描述了EF6框架描述这里。
Pff,现在我们有了背景知识,这是我的问题:
我已经创建了模型并从中生成了数据库。实际接口层的代码生成由edmx完成。为了进行单元测试,我遵循了上述教程,并修改了相关字段以匹配我的数据库模型。(可在http://i.imgur.com/julse1Y.png?1中找到它,很遗憾,我没有代表在帖子中包含该图片...)。
但是,我不需要每个测试仅包含一些子集的所有数据。我想要一种情况,我可以在测试的设置中指定要加载哪些表,或者加载依赖项的深度。
我遇到的问题是,在指定相关外键时,相关数据未与当前DBSet一起加载。例如,当为连接集设置数据时,我希望条目链接到相关数据,在这种情况下,是节点集的元素:
var context = new TestContext();
context.NodeSet.Add(new Node { NodeID = 1 });
context.NodeSet.Add(new Node { NodeID = 2 });
context.ConnectionSet.Add(new Connection { ConnID = 1, ToNodeID = 1, FromNodeID = 2 });
var conn = context.ConnectionSet.First();
var fromNode = conn.FromNode;
var toNode = conn.ToNode;
Run Code Online (Sandbox Code Playgroud)
在此示例中,指定的Connection的FromNode属性返回null。理想的情况是该模拟具有将ToNodeID密钥与相关对象相关联的能力。此外,我希望加载顺序与解决iaw的关键约束有关,以便解析相应节点必须存在的FromNode字段。
我乐于接受有关此特定问题的所有建议,但也欢迎你们中的任何人知道模拟EF6模型优先数据库设计的更富建设性的方法。
提前致谢!
我在MSDN中使用了EF6中新的测试双打.VS2013与Moq和nUnit.一切都很好,直到我不得不这样做:
var myFoo = context.Foos.Find(id);
然后:
myFoo.Name = "Bar";
然后 :
context.Entry(myFoo).Property("Name").IsModified = true;
此时是我收到错误的地方:
附加信息:无法为属性"名称"调用成员"IsModified",因为上下文中不存在"Foo"类型的实体.要向上下文添加实体,请调用DbSet的Add或Attach方法.
虽然,当我用AddWatch检查上下文中的'Foos'时,我可以在运行测试之前看到我添加的所有项目.所以他们在那里.
我从文章中创建了FakeDbSet(或TestDbSet).我将每个FakeDbSet放在构造函数中的FakeContext中,每个构造函数都被初始化.像这样:
Foos = new FakeDbSet<Foo>();
我的问题是,是否可以使用测试双精度场景使用FakeDbSet和FakeContext,以便从测试双重访问DbEntityEntry和DBPropertyEntry?谢谢!
entity-framework ×11
c# ×5
unit-testing ×4
asp.net-mvc ×2
.net ×1
architecture ×1
code-first ×1
covariance ×1
database ×1
dbcontext ×1
exception ×1
linq ×1
mocking ×1
moq ×1
testing ×1