【发布时间】:2013-04-11 06:48:15
【问题描述】:
我目前正在开发一个 ASP .NET MVC 3 Web 应用程序作为原型,其中 Code First 作为数据访问层。现在我有点困惑把我的代码放在哪里。
我有一个班级客户和一个班级项目。项目对其客户具有导航属性。
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Project
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Customer Customer { get; set; }
}
我使用这两个类通过 codefirst 进行数据访问。
public class MyContext : DbContext
{
public DbSet<Customer> Customers { get; set; }
public DbSet<Project> Projects { get; set; }
}
我了解到最好不在我的 MVC 视图中直接使用这些数据访问类 - 所以我为单个客户创建了一个 ViewModel (CustomerListModel) 和一个 DTO。
public class CustomerDto
{
public int Id { get; set; }
public string Name { get; set; }
public int ProjectCount { get; set; } <== this property is in question
}
public class CustomerListModel
{
public List<CustomerDto> Customers;
}
在我的控制器中,我从执行实际数据访问的(服务)类中获取客户。
public class CustomerService : IDisposable
{
private MyContext db;
public CustomerService()
{
db = new MyContext();
}
public IEnumerable<Customer> GetAllCustomers()
{
return db.Customers.ToList<Customer>();
}
}
在我的控制器中,我调用获取所有客户的方法。
public ViewResult Index()
{
//Mapper.CreateMap<Customer, CustomerDto>();
var customerList = new List<CustomerDto>();
foreach (var customer in rep.GetAllCustomers())
{
var cust = new CustomerDto();
cust.Id = customer.Id;
cust.Name = customer.Name;
cust.Rate = customer.Rate;
==> cust.ProjectCount = customer.ProjectCount; <=====
customerList.Add(cust);
}
var viewModel = new CustomerListModel()
{
Customers = customerList //Mapper.Map<IEnumerable<Customer>, List<CustomerDto>>(rep.GetAllCustomers())
};
return View(viewModel);
}
我要问的是 - 例如,将单个客户的 ProjectCount 放在哪里。我可以把它放到客户类中
public int ProjectCount
{
var db = new MyContext();
return db.Projects.Where(x => x.Customer.Id == this.Id).Count();
}
...但是我会有两个可以访问数据的地方 - 服务类和客户类。
我也可以将此代码放在我的 ServiceClass 中:
public int GetProjectCount(Customer customer)
{
return db.Projects.Where(x => x.Customer.Id == customer.Id).Count();
}
...但后来我不得不从控制器调用它:
foreach (var customer in rep.GetAllCustomers())
{
var cust = new CustomerDto();
cust.Id = customer.Id;
cust.Name = customer.Name;
cust.Rate = customer.Rate;
cust.ProjectCount = rep.GetProjectCount(customer); <==
customerList.Add(cust);
}
...我也可以从客户类的 getter 中从我的服务类调用此方法。
public int ProjectCount
{
get
{
return new CustomerService().GetProjectCount(this);
}
}
所有描述的方法都有效并给了我正确的结果 - 但是我想以正确的方式做 - 你将如何做 - 或者我完全偏离轨道;-)?
谢谢!
【问题讨论】:
-
我会说 - 通常可以,最好创建一个接口
ICustomerService(CustomerService 将实现该接口),然后将此接口与 DI 一起使用。如果您正在使用非通用存储库方法(如果您有大量表,这可能会有点麻烦,但对于较小的数据库,它非常简单,易于管理和调试),我会将GetProjectCount(int customerId)作为接口中的方法。 -
只是为了澄清我对您的理解正确:从 ICustomerService 实现 CustomerService - 在 CustomerService 中实现 GetProjectCount 方法,然后注入什么(DbContext?)?然后使用我的控制器中的 GetProjectCount 我提取数据?
-
注入整个
ICustomerService。在 Autofac 中,它看起来像这样(Global.asax):var builder = new ContainerBuilder(); builder.Register(service => new CustomerService()).As<ICustomerService>().InstancePerHttpRequest(); ...。然后在控制器的构造函数中传递ICustomerService作为参数,将其分配给控制器的成员,瞧,您可以使用存储库。 :) 是的,那么您可以使用该成员在控制器中调用 GetProjectCount。
标签: c# asp.net-mvc model-view-controller architecture code-first