gpt4 book ai didi

c# - 在哪里放置访问数据库的方法

转载 作者:行者123 更新时间:2023-11-30 22:28:52 26 4
gpt4 key购买 nike

我目前正在开发一个 ASP .NET MVC 3 Web 应用程序作为原型(prototype),使用 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 View 中直接使用这些数据访问类 - 因此我为单个客户创建了一个 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;
}

在我的 Controller 中,我从执行实际数据访问的(服务)类获取客户。

public class CustomerService : IDisposable
{
private MyContext db;
public CustomerService()
{
db = new MyContext();
}

public IEnumerable<Customer> GetAllCustomers()
{
return db.Customers.ToList<Customer>();
}
}

在我的 Controller 中,我调用了获取所有客户的方法。

    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();
}

...但后来我不得不从 Controller 调用它:

        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);
}
}

所有描述的方法都有效并给我正确的结果 - 但是我想以正确的方式去做 - 会怎么做 - 或者我完全偏离轨道 ;-)?

谢谢!

最佳答案

以下是我的看法,只是为了回顾一下我在评论中写的内容。我不能说这是否是“可行的方法”,但我认为这是一个可行的解决方案。

因此,如果您使用非通用方法(如我所提到的)直接、易于管理和调试具有少量表的小型数据库,您可以按以下方式进行:

public interface ICustomerService
{
IEnumerable<Customer> GetAllCustomers();
// and other methods you'd like to use
}

public sealed class CustomerService : ICustomerService
{
private YourContext context = new YourContext();
// or, alternatively, even something along these lines
private YourContext context;
public CustomerService()
{
context = ContextFactory.GetDBContext();
}
//----

public IEnumerable<Customer> GetAllCustomers()
{
// here goes the implementation
}
}

public class YourController : Controller
{
private ICustomerService customerService;
public YourController(ICustomerService service)
{
customerService = service;
}
// and now you can call customerService.GetAllCustomers() or whatever other methods you put in the interface.
}

题外话 - 数据库上下文工厂可能看起来像那样,以防你想,例如稍后更改数据库连接:

public static ContextFactory
{
public static YourContext GetDBContext()
{
return new YourContext();
}
}

当然,这种简单的设置适用于任何选择的 IoC 容器,我的是用于网络应用程序的 Autofac,它位于 Global.asax Application_Start 中:

var builder = new ContainerBuilder();
builder.Register(service => new CustomerService()).As<ICustomerService>().InstancePerHttpRequest();
builder.RegisterControllers(typeof(MvcApplication).Assembly);
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

依赖注入(inject)使得以后测试 Controller 变得更容易,因为您可以使用许多模拟助手之一模拟任何东西(例如准备好的项目列表)的数据库访问。

但是,如果您的大多数存储库方法都相似,您可能需要查看更多 general solution (it's for database-first, but can be applied to code-first too)这将更适合您的需要,因此您不必重复代码,但是 - 代码可能看起来有点复杂。 :)

关于c# - 在哪里放置访问数据库的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10550537/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com