我刚刚开始使用Entity Framework,它创建了一个Context类,我可以使用它来获取我需要的所有数据。但是我面临一个关于我应该如何组织代码的问题,通过观看演示,这个人只是使用框架并对控制台应用程序上的所有内容进行编码。什么是使用Entity Framework的最佳方式,它看起来很干净?我的意思是......现在使用aspx页面,我可以使用aspx.cs来获取数据或保存数据。但是我不希望这样,我希望它更有条理,尽管实体框架几乎通过创建对象等来完成所有事情。但是,我仍然需要使用像
这样的东西using(var myobject = new MyContextData())
{
blah blah..
}
你会说编写可以封装这些调用的类会更好吗?我真的很感激任何输入,因为它真的会让我成为使用实体框架的更好的程序员。
此致
答案 0 :(得分:1)
每个提供EF教程的人都应该提出这个问题。很难说什么是最好的方法,但是将所有代码放在代码隐藏类(aspx.cs)中并没有帮助扩展性和可测试性。请尝试阅读这篇文章:
不仅是asp.net上的官方教程,而且它主要表明,框架EF可以在当前花哨的Repository pattern
答案 1 :(得分:0)
您正在创建处理EF的类。
这样做的最大好处是可以轻松进行单元测试。
早期测试和测试通常总是一个好主意。
我建议将您的EF相关课程放在一个单独的项目中。
答案 2 :(得分:0)
尝试将代码划分为界面和业务逻辑层。如果您的代码不是那么大,您可以将其放入单独的文件中。但将其置于不同项目中的良好做法。然后你可以从BL
调用所需的方法public string GetAddress(int personID)
{
string res = string.Empty;
using (var context = new PersonEntities())
{
var persons = from b in context.Persons
where b.ID == personID
select b;
var person = persons.FirstOrDefault();
res=person.AddressLine;
}
return res;
}
答案 3 :(得分:0)
修改强>
我认为Generic Repository是Anti Pattern。但我不明白@TomTom评论。
原始答案:
正如RadimKöhler所说,你需要实施Repository and Unit of Work patterns
但他在我看来提供的文章并不完全正确。
在我目前的工作中,我使用以下实现这些模式。
例如,我们有三种类型的实体:Person, Good and Order
。我为人员创建了存储库。通常情况下,存储库不能是通用的。它必须包含表示此实体的特定查询的方法。因此,通过查看存储库的接口,您可以知道为实体(例如,Person)执行了哪些类型的查询。正如您将看到的,我为名为PersonWrap
的人创建了DTO。要从Person创建PersonWrap并从PersonWrap更新Person,您可以使用AutoMapper而不是PersonWrap()
构造函数和Update()
方法。因为EntityFramework DbContext
实现了Unit of Work
模式,所以您只需要为存储库方法提供已创建的DbContext。如果存储库方法是一个单独的操作,并且您不需要此方法之外的DbContext,则可以在此方法中创建并处理它。
public class Person {
public int Id { get; set; }
public string FirstName { get; set; }
public string SecondName { get; set; }
public DateTime RegistrationDate { get; set; }
public List<Order> Orders { get; set; }
}
public class Good {
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
public class Order {
public int Id { get; set; }
public Person Person { get; set; }
public Good Good { get; set; }
public int Count { get; set; }
}
public class MyDbContext: DbContext
{
public IDbSet<Person> Persons { get { return Set<Person>(); }}
public IDbSet<Good> Goods { get { return Set<Good>(); }}
public IDbSet<Order> Orders { get { return Set<Order>(); }}
}
public class PersonRepository {
public IEnumerable<Person> GetAll() {
using (var context = new MyDbContext()) {
return context.Persons.ToList();
}
}
public IEnumerable<Person> GetLastWeekPersons() {
using (var context = new MyDbContext()) {
return context.Persons.Where(p => p.RegistrationDate > new DateTime().AddDays(-7)).ToList();
}
}
public Person GetById(int id, MyDbContext context) {
return context.Persons.Include(p => p.Orders).FirstOrDefault(p => p.Id == id);
}
public Person GetById(int id) {
using (var context = new MyDbContext()) {
return GetById(id, context);
}
}
}
public class PersonWrap {
public int Id { get; set; }
public string FirstName { get; set; }
public string SecondName { get; set; }
public int OrderCount { get; set; }
public PersonWrap(Person person) {
Id = person.Id;
FirstName = person.FirstName;
SecondName = person.SecondName;
OrderCount = person.Orders.Count;
}
public void Update(Person person) {
person.FirstName = FirstName;
person.SecondName = SecondName;
}
}
public class PersonDetailsViewController {
public PersonWrap Person { get; protected set; }
public PersonDetailsViewController(int personId) {
var person = new PersonRepository().GetById(personId);
if (person != null) {
Person = new PersonWrap(person);
}
}
public void Save() {
using (var context = new MyDbContext()) {
var person = new PersonRepository().GetById(Person.Id, context);
Person.Update(person);
context.SaveChanges();
}
}
}