业务对象中的ID是否应该是只读的?

时间:2009-08-11 10:44:35

标签: c# business-logic

在我看来,业务对象的ID字段应该是只读的(公共get和私有集),因为根据定义,ID永远不会改变(因为它唯一地标识数据库中的记录)。

这会在您创建新对象(ID尚未设置)时产生问题,通过存储过程将其保存在数据库中,例如,该存储过程将返回新创建的ID,然后如果ID将如何将其存储回对象中属性是只读的吗?

示例:

Employee employee = new Employee();  
employee.FirstName="John";  
employee.LastName="Smith";  

EmployeeDAL.Save(employee);

如果此属性是只读的,那么Save方法(实际连接到数据库以保存新员工)如何更新Employee对象中的EmployeeId属性(这应该是因为EmployeeId在创建后永远不会更改)。

看起来Id应该可以由DAL写入,并且只读给世界其他地方。如果DAL类和Business对象在不同的​​程序集中,您如何实现这一点?

我不想在Employee类中创建一个Save方法,因为这个类应该与数据库无关。

5 个答案:

答案 0 :(得分:2)

另一种可能的解决方案是将Employee声明为: -

public class Employee
{
    public int Id { get; internal set; }
}

...只要Employee和DAL类在同一个程序集中
我声称不喜欢它,但我已经使用过它。

答案 1 :(得分:1)

您可以使DAL方法只返回更新的对象:

public class EmployeeDAL
{
    Employee EmployeeDAL.Save (Employee employee)
    {
        // Save employee
        // Get the newly generated ID
        // Recreate the object with the new ID and return it
    }
}

或者,您可以在代码中生成新ID,使用此ID实例化对象,然后让DAL保存它。

如果您希望在保存操作期间更新对象,则必须公开此属性。

我个人喜欢创建不可变的对象,那些只能通过将所有值传递给构造函数来设置的对象。使用这种方法,您只需创建一个要保存的对象,然后将其与数据库中分配的ID一起检索并将其返回给调用者。

答案 2 :(得分:1)

只有在之前尚未设置ID设置时,才可以设置ID允许设置:

public class Employee
{
    private int? m_ID;

    public int? ID
    {
        get { return m_ID; }
        set
        {
            if (m_ID.HasValue())
                throw ...
            m_ID = value;
        }
    }
}

或者,我认为某些框架支持这种类型的功能(例如,我认为NHibernate将允许您在ID字段上拥有私有的setter。)

答案 3 :(得分:1)

如何只允许DAL之外的代码通过不为Id字段(以及任何其他不可变字段)提供setter的接口引用该对象:

public interface IEmployee
{
    Int32 Id {get;}
    String Name {get;set;}
    // ... and so on ...
}

public class Employee: IEmployee
{
    Int32 Id {get;set;}
    String Name {get;set;}
}

DAL可以根据需要进行设置,但消耗代码不能。

答案 4 :(得分:0)

怎么样:

Employee employee = new Employee(EmployeeDAL.GetNextID());

这也应该使您的保存代码更简单。