Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/328.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.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# 活动记录模式和使用静态方法进行组操作的最佳实践_C#_.net_Activerecord_Design Patterns - Fatal编程技术网

C# 活动记录模式和使用静态方法进行组操作的最佳实践

C# 活动记录模式和使用静态方法进行组操作的最佳实践,c#,.net,activerecord,design-patterns,C#,.net,Activerecord,Design Patterns,他们关于设计模式的说法是正确的,它们只是已经普遍使用的技术的体现。自1985年以来,我一直在使用活动记录模式 此模式的属性之一是在实现中使用静态成员来执行返回基础数据集合的搜索 class Customer { static Customer FindCustomerById( int Id ) { ... } static Customer[] FindActiveCustomers() { ... } } 在许多需要更大灵活性的情况下,我会打破封装,并包括一个方法,如 st

他们关于设计模式的说法是正确的,它们只是已经普遍使用的技术的体现。自1985年以来,我一直在使用活动记录模式

此模式的属性之一是在实现中使用静态成员来执行返回基础数据集合的搜索

class Customer { 
   static Customer FindCustomerById( int Id ) { ... } 
   static Customer[] FindActiveCustomers() { ... }
}
在许多需要更大灵活性的情况下,我会打破封装,并包括一个方法,如

static Customer[] FindCustomers( string criteria ) { ... } 
我们可以称之为

Customer[] customers = Customer.FindCustomers( "LastName = 'Smith'" );
当然,这是我在C中使用此模式时的遗留问题,显然不是一种最佳实践,如果使用不当,可能会导致SQL注入和其他问题

是否有一种合适的模式或实践可以应用,使客户类别成为此类搜索的“标准”

例如,假设我想找到姓史米斯的客户,我可以考虑写一个实现,例如:

static Customer[] FindCustomers( Customer customer ) { ... }
被称为(当然有合适的构造函数):


还是创建一个定义标准的co类更好?

仅仅通过使用LINQ,我喜欢传递表达式而不是字符串的想法。但是,也许那只是我?我也不喜欢ActiveRecord,因为它在同一个对象中混合了状态和行为。很好的包装,但不是模型和数据访问的干净分离

我见过客户类被传递到活动记录的情况,但如果您这样做,那么存储库模式会更干净,并将行为与状态分开。然而,我认为使用您在活动记录中已有的投资并传递一个对象并没有什么错


如果您想创建一个criteria类,那么您将得到一个策略模式,这可以使您的活动记录比现在更活跃。然而,它是一种适用的模式,也将解决任何注入问题。

尽管它将您推出数据库级别,但您可以使用类似于比较器的东西。我不知道C#,所以我只是捏造了它,但你知道要点:

class CustomerLastNameEvaluator : IEvaluate
{
    private Customer _customer;

    public CustomerLastNameEvaluator (String lastName)
    {
        _customer = new Customer (lastName);
    }

    bool IEvaluate.Evaluate(Customer c)
    {
        return (_customer.LastName == c.LastName);
    }
}

Customer[] customers = Customer.FindCustomers( new CustomerLastNameEvaluator("Smith") );

如果没有理由不这样做,我会提供如下方法:

public static IEnumerable<Customer> AllCustomers()
{
   return Customers.AsEnumerable();
}
公共静态IEnumerable AllCustomers()
{
返回客户。AsEnumerable();
}

如果您有理由不这样做,您需要阐明这些理由并详细检查它们,以便设计正确的解决方案。

请查看codeplex上的WWPlatform DataAccess示例。它展示了一个很好的例子,通过存储库模式将搜索规范实例作为参数提供。

只要可能的条件限制在公开的属性上,我不认为这真的破坏了封装。我指的是,当使用通用SQL WHERE语法条件字符串时,封装被破坏了。在这种情况下,条件不基于类的成员字段。通过要求类的使用者使用SQL来指定标准,我过度公开了实现细节。
public static IEnumerable<Customer> AllCustomers()
{
   return Customers.AsEnumerable();
}