.net 如何在面向对象代码中设置ID
当涉及到面向对象编程(比如说三层应用程序)时,我有点困惑。这里只是我尝试做的一个小例子(我将缩短数据库设计以使其变得简单)。假设我正在制作一个票务服务台系统。票证有描述、负责人、截止日期,当然还有ID(唯一) 假设ID只是一个integer类型的标识列,并自动获取其值(SQL Server)。也就是说,它只有在插入完成后才获得其值 现在,只需一些示例伪代码(可能不正确,所以不要让语法困扰您,只是尝试获得有关如何存储ID的答案) 我可以很容易地创建一个票证类.net 如何在面向对象代码中设置ID,.net,oop,design-patterns,.net,Oop,Design Patterns,当涉及到面向对象编程(比如说三层应用程序)时,我有点困惑。这里只是我尝试做的一个小例子(我将缩短数据库设计以使其变得简单)。假设我正在制作一个票务服务台系统。票证有描述、负责人、截止日期,当然还有ID(唯一) 假设ID只是一个integer类型的标识列,并自动获取其值(SQL Server)。也就是说,它只有在插入完成后才获得其值 现在,只需一些示例伪代码(可能不正确,所以不要让语法困扰您,只是尝试获得有关如何存储ID的答案) 我可以很容易地创建一个票证类 public class Ticket
public class Ticket
{
private string m_description;
private date m_duedate;
private string m_responsible;
private int m_id; //should this be read only ??? or...how
//then I can have a bunch of Properties to get / set these private variables
public Property Responsible{
get
{ return m_responsible; }
set
{ m_responsible = value; }
}
//and so on..again dont worry about syntax. Now should I have a get / set for the ID?
}
好的,我有一个名为ticket的类。但是当我创建一个ticket对象并需要从BLL(业务逻辑层)插入它时会发生什么呢
//也就是说,将它传递给BLL,由BLL完成它的工作,然后通过INSERT语句将它传递给DAL,然后返回数据库给它的ID号
所以我的问题是,我需要如何或何时分配t.ID,或者在插入t.ID之后,我甚至需要给出t.ID。我总是对OOP感到困惑,因为我倾向于认为它比仅仅传递一系列参数更复杂
好的,在有人帮助我了解我是否需要ID上的get/set,以及我是否应该将该值传递回我的接口之后。我的第二个问题是更新怎么办?
假设最终用户找到了一张票证,那么在我的界面上,我检索了一些票证数据,有人想要更新,比如说描述和截止日期。当我“提交”这些更改时,我是否应该创建一个ticket对象,设置所有get/set属性值,就这样?或者我应该把ID号和所有参数传递给我的BLL,让它处理所有的事情吗
希望这一切都有意义
非常感谢各位 答案是它取决于您使用的框架或库 并非所有BLL都允许您简单地说
Ticket t=new Ticket()
,您可能必须使用t=b.CreateTicket()
或其他方法。Id可以是临时值,也可以是空/0,直到它被持久化
关于你问题的第二部分:
如果要更新票证,您肯定不会创建新的票证对象。更新现有对象
也许你应该根据特定的库或技术来澄清或重新提问。通常我会使用某个键值(即-1)作为默认的未保存ID。 然后,它将向上游传递到将保存此对象的相关DB层 并更新ID,如有必要,将其返回(否则,如果需要,请更新最终客户端请求)。 我经常在构建对象时使用默认值的键default 在以前的一些项目中,我使用Guid作为键,因为它们可以在客户机/应用程序服务器上生成,而无需数据库来生成键(以及随后将外键更新到父对象)。这可以节省大量执行SQL的时间,因为它可以更容易地进行批处理)。如果需要,可以使用Guid梳更快地生成密钥。但是,如果您需要增量密钥,这可能不是一个选项
这可能因框架/技术/基础设施的不同而有所不同。使用NHibernate或其他合适的O/R映射程序,您甚至不会遇到这个问题。该属性可以是只读的,并且可以在插入之前或之后由ORM本身设置。除此之外,如果您是手工操作,则可以将其设置为只读,并在需要时使用少量反射从DAL设置ID,而不会违反封装 另外,为什么要将对象传递给BLL?对象本身不应该实现自己的业务逻辑吗?这就是制作物体的意义所在。否则,您应该只使用强类型数据集。听起来你在做“贫血领域模型”,这很糟糕:
也许此列表将帮助您:
public class Ticket : IEquatable<Ticket>
{
public static Ticket Create()
{
return new Ticket { Id = Guid.NewGuid() };
}
/// Id must be really unique
public Guid Id {get; private set;}
/// other properties
/// ...
bool IEquatable.Equals(Ticket ticket)
{
return ticket != null && ticket.Id == this.Id;
}
/// hidden ctor
protected Ticket() {}
}
公务舱票:可接受
{
公共静态票证创建()
{
返回新票证{Id=Guid.NewGuid()};
}
///Id必须是唯一的
公共Guid Id{get;private set;}
///其他属性
/// ...
bool IEquatable.Equals(票证)
{
回程票!=null&&ticket.Id==this.Id;
}
///隐藏的导体
受保护的票证(){}
}
您可以尝试这样的方法。代码并不完美,但它会给你一个想法。对不起,我正试图让这比我应该做的要快,所以这很艰难
// returns Record number of object
public int Insert()
{
SqlConnection conn = new SqlConnection(dbstring);
SqlCommand insertCommand = new SqlCommand("mystoredprocedure");
SqlParameter newRecNo = new SqlParameter();
newRecNo.Direction = ParameterDirection.ReturnValue;
conn.Open();
insertCommand.ExecuteNonQuery(); // Your sqlparameter will now contain the recno
conn.close(); // use try/catch, etc.
return newRecNo.value;
}
public static MyObject GetData(int TicketID)
{
// Get object data from DB.
}
In the stored procedure to insert, put this in:
declare @recno int
set @recno = @@identity
return @recno
有几点:
1--is sooo 1985 dude.:)
2--你在这里重新发明轮子。有很多好的方法可以以标准化的方式处理持久性,让您能够继续编写域
3--好的,如果你绝对不能使用像NHibernate这样的ORM框架,或者,上帝禁止,实体框架,那么我建议你遵循ORM框架使用的标准模式之一,比如或。是的,您需要在新对象被持久化后分配。Martin Fowler的ActiveRecord和DataMapper模式都使用“插入”方法将新对象持久化到数据库中。在其他ORM框架(如Rails)中,使用了类似的方法“save”,新对象可以通过调用“new_record”等接口来报告它是否已被持久化,该接口将返回TRUE,直到调用“save”或“insert”。在调用其中一个方法之前,ID字段通常默认为0或-1,这两个都是无效的PKID。在“插入”或“保存”中,检索新id字段并将其分配给新对象的id字段。@Peter Lillevold的编辑:“Oriented”是不太常用的英国拼写;这不是一个错误。对不起,这没有意义。为什么要从中创建票证
// returns Record number of object
public int Insert()
{
SqlConnection conn = new SqlConnection(dbstring);
SqlCommand insertCommand = new SqlCommand("mystoredprocedure");
SqlParameter newRecNo = new SqlParameter();
newRecNo.Direction = ParameterDirection.ReturnValue;
conn.Open();
insertCommand.ExecuteNonQuery(); // Your sqlparameter will now contain the recno
conn.close(); // use try/catch, etc.
return newRecNo.value;
}
public static MyObject GetData(int TicketID)
{
// Get object data from DB.
}
In the stored procedure to insert, put this in:
declare @recno int
set @recno = @@identity
return @recno