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

发布于 2024-08-01 23:50:25 字数 582 浏览 6 评论 0原文

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

当您创建一个新对象(尚未设置 ID)时,这会产生一个问题,通过存储过程将其保存在数据库中,例如返回新创建的 ID,那么如果读取 ID 属性,如何将其存储回对象中-仅有的?

示例:

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

EmployeeDAL.Save(employee);

如果 Employee 对象中的 EmployeeId 属性是只读的,Save 方法(实际上连接到数据库来保存新员工)如何更新该属性(这应该是因为 EmployeeId 一旦创建就永远不会改变) 。

看起来 Id 应该可以由 DAL 写入,并且对于世界其他地方来说应该是只读的。 如何实现这一点,特别是如果 DAL 类和业务对象类位于不同的程序集中?

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

In my mind the ID field of a business object should be read-only (public get and private set) as by definition the ID will never change (as it uniquely identifies a record in the database).

This creates a problem when you create a new object (ID not set yet), save it in the database through a stored procedure for example which returns the newly created ID then how do you store it back in the object if the ID property is read-only?

Example:

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

EmployeeDAL.Save(employee);

How does the Save method (which actually connects to the database to save the new employee) update the EmployeeId property in the Employee object if this property is read-only (which should be as the EmployeeId will never ever change once it's created).

It looks like the Id should be writable by the DAL and read-only for the rest of the world. How do you implement this especially if the DAL classes and the Business object ones are in different assemblies?

I don't want to create a Save method in the Employee class as this class should have nothing to do with the database.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

原来是傀儡 2024-08-08 23:50:25

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

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

... 前提是 Employee 和 DAL 类位于同一个程序集中

我并不声称喜欢它,但我已经使用过它。

Another possible solution is to declare Employee as :-

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

... provided that the Employee and DAL classes are in the same assembly

I don't claim to like it but I have used it.

甜心小果奶 2024-08-08 23:50:25

您可以使 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,并将其返回给调用者。

You can make your DAL method just return an updated object:

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

Alternatively, you can generate a new ID in code, instantiate an object with this ID then ask your DAL to save it.

If you wish that your object was updated during Save operation you will have to make this property public.

I personally like to create immutable objects, those you can only setup once by passing all the values into constructor. With this approach you would just create an object to be saved, then retrieve it back along with the assigned ID from the database and return it to the caller.

单身情人 2024-08-08 23:50:25

仅当之前尚未设置过时,您才可以为 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 字段上拥有私有设置器)。

You could make your setter for the ID allow set only if it has not already been set before:

public class Employee
{
    private int? m_ID;

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

Alternatively, I think some frameworks support this type of functionality (for example, I think NHibernate will allow you to have a private setter on an ID field).

财迷小姐 2024-08-08 23:50:25

只允许 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 可以根据需要设置它,但使用代码不能。

How about only allowing code outside the DAL to refer to the object through an interface which doesn't supply a setter for the Id field (and any other immutable fields):

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

The DAL can set it as required, but the consuming code can't.

没有伤那来痛 2024-08-08 23:50:25

怎么样:

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

这也应该会让你的保存代码更简单。

How about:

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

This should also make your save code simpler.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文