Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 类构造函数和Get设计_C#_Class_Constructor_Data Access - Fatal编程技术网

C# 类构造函数和Get设计

C# 类构造函数和Get设计,c#,class,constructor,data-access,C#,Class,Constructor,Data Access,在设计类和构造函数时,我有一个关于获取记录的问题 在一个例子中,如果我有一个汽车类 public Car { ... } 我可以选择创建一个构造函数,该构造函数可以获取某个汽车实例,例如: public Car(int carID) { //Get car from database } 或者我可以写一个公开的方法来获得汽车: public Car GetCarByID(int carID) { //Get car from database } 是否有获取类实例的

在设计类和构造函数时,我有一个关于获取记录的问题

在一个例子中,如果我有一个汽车类

public Car
{
    ...
}
我可以选择创建一个构造函数,该构造函数可以获取某个汽车实例,例如:

public Car(int carID)
{
    //Get car from database
}
或者我可以写一个公开的方法来获得汽车:

public Car GetCarByID(int carID)
{
    //Get car from database
}
是否有获取类实例的首选(最佳实践)方法?代码似乎是读取cleaner以获取对象的实例:

Car MyCar = new Car(5);
vs


一个简单的解决方案是使用,如下所示:

public static Car GetById(int carId)
{
    ... Load car and return it ...
}
然后你可以这样称呼它:

Car myCar = Car.GetById(18); 

我建议将数据库访问与域模型类(如Car)分开

这可以通过将所有数据库访问检索操作放在它们自己的类集中来实现。这些被称为存储库。制作这些存储库有不同的方法。这取决于数据在数据库中的存储方式以及是否使用实体框架。一些人更喜欢通用存储库,而另一些人根本不喜欢这种通用方法。但底线是存储库负责访问数据库以进行对象检索和存储。它不应该由域对象ie Car本身完成,因为它应该只有属于Car的操作以及使其成为Car对象的操作。将汽车存储在数据库中不是汽车应该知道的事情

可以在此处找到使用存储库模式的示例:

在MSDN上还有一篇关于存储库模式的好文章:

底线是使用存储库访问数据库。它用于从数据库加载和存储数据,并提供额外的抽象层。如果需要,您可以为每个存储库创建一个接口,它也允许您进行单元测试


比在不属于它们的类中创建方法要好得多。

为了解决关于关注点分离的评论,我建议如下:

public class Car
{
    public string Make {get; set;}
    public string Model {get; set;}
    // additional properties here.
}

public static class CarFactory
{
    public static Car CreateCar(string modelId)
    {
        Car car = new Car();
        // Load the car via whatever mechanism you wish;
        // e.g., web service, database, etc.
        return car;
}

Car fordFairlane = CarFactory.CreateCar("57fordFairlane");

这将使创建汽车对象的代码与汽车对象本身分开,并允许您在不接触汽车类的情况下更改汽车的创建方式。

正如我在评论中所说,我将这样做以管理汽车,并允许按id或任何其他您希望加载汽车的方式加载汽车

public class Car
{
    public int Id { get; set; }
    public Car() { }
    public Car(int id) { Id = id; }
}

public class CarCollection
{
    public List<Car> Cars { get; set; }

    public void AddCar(Car car) { Cars.Add(car); }

    public Car GetById(int id) { return Cars.Single(x => x.Id == id); }

    public CarCollection(List<Car> cars) { Cars = cars; }
    public CarCollection(Car car) { Cars = new List<Car>() { car }; }
}
公车
{
公共int Id{get;set;}
公共汽车(){}
公共汽车(int id){id=id;}
}
公营车辆收集
{
公共列表车辆{get;set;}
公共空间添加汽车{Cars.Add(Car);}
公共汽车GetById(int-id){return Cars.Single(x=>x.id==id);}
公共车辆收集(列出车辆){cars=cars;}
公共汽车收集(汽车){Cars=新列表(){Car};}
}

在本例中,我将使用一个名为car的类来处理所有基本信息。(就像身份证一样)。然后我会有一个叫做CarCollection的类,它包含一个集合中的汽车。在这个类中,我将使用GetCarById方法。在这种方法中,我将搜索收集的汽车并返回带有该id的汽车。这个问题是基于观点的,尽管它在这里是离题的。分离关注点,如果您的
汽车
类确实是一个包含关于
汽车
信息的类,您应该使用数据访问层来构造
car
对象,而不需要
car
了解数据库。为什么汽车应该知道如何从数据库中获取自己?你的两个建议都不好,都违反了SRP。这并不能提供一个简单的方法来通过id装载汽车。这只是创建一个带有id的新车。装载代码并不重要,所以我没有添加很多无关的DB代码。该示例的重要之处在于,它强调了如何将创建对象的代码保留在对象的类代码之外。因此,在调用构造函数之后会出现注释。不,注释清楚地表明可以从数据库中加载汽车。在这个所谓的“工厂”中添加一种存储方式,你拥有的就是一个存储库。汽车绝对不应该用这样的方法进行扩展。它违反了SRP,很难进行单元测试。哦,这要看情况而定。对于一个小项目,添加这样一个静态方法可以节省您的时间,而无需花费任何费用。这就是为什么我说这是一个简单的解决方案。谢谢你的解释。虽然这带来了另一个问题,但如果我有一个DriveCar()方法需要从数据库访问cars max speed,我认为DriveCar()方法应该属于类定义,它会调用car repository类来获得max speed吗?还是我的想法完全错了?当汽车存储库检索到属于汽车的数据时,它应该检索到汽车的所有重要方面,以及汽车成为汽车的原因。最大速度显然是车辆的一个属性,因此,是的,当您从Db加载车辆时,应该直接检索它。通过进行域驱动设计并仅使用聚合根作为入口点,您可以在这个方向上走得更远。但这是一个不同的话题。我喜欢这个例子,但是实现似乎需要很多开销。例如,要按Id获取汽车,我首先必须实例化一个汽车对象,然后实例化一个CarCollection对象来填充汽车对象?其他一些示例使用静态类,但从我的阅读来看,静态类似乎不应该以这种方式使用?我不认为这会占用大量开销,因为您需要将所有汽车存储在列表/数组/字典/其他数据结构中。该集合允许轻松访问您想要的汽车,而无需编写静态方法。在这些静态方法中,您必须将汽车的集合传递给它们,以便它们能够迭代汽车并选择所需的汽车。上面的类已经处理了这个问题。作为前任
public class Car
{
    public int Id { get; set; }
    public Car() { }
    public Car(int id) { Id = id; }
}

public class CarCollection
{
    public List<Car> Cars { get; set; }

    public void AddCar(Car car) { Cars.Add(car); }

    public Car GetById(int id) { return Cars.Single(x => x.Id == id); }

    public CarCollection(List<Car> cars) { Cars = cars; }
    public CarCollection(Car car) { Cars = new List<Car>() { car }; }
}