How to set an identifier in object oriented code

I'm a little confused when it comes to object-oriented programming, such as a three-tier application. Here is just a small example of what I'm trying to do (I will shorten the database design to make it simple). Suppose I make a help desk system. The ticket contains a description, a responsible person, a period and, of course, an identifier (unique).

Suppose an identifier is only an IDENTITY column that is of type integer and automatically gets its value (SQL Server). That is, it gets its value only after the insert is completed.

Now just some kind of pseudo-code example (this may be wrong, so don't let the syntax fail, just trying to get an answer on how to save the identifier).

I could easily create a Ticket class

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

So, I have this class called ticket ... but what happens when I create a ticket object and it needs to be inserted from my BLL (Business Logic Layer)

 Bll b = new Bll(); Ticket t = new Ticket(); t.Responsible = someString; t.DueDate = someDate; t.Description = someLongString; //use the BLL to create a ticket object and pass it to the DAL ? //then assign the ID from the database to t.ID ??? t.ID = bll.InsertTicket(t); 

//, which passes it to the BLL, which performs its task, and passes it to the DAL, executes the INSERT statement, and then returns the identification number provided to it by the database.

So my question is how or when do I need to assign t.ID or do I even need to give after inserting it, I am done. I am always confused with OOP, because I tend to think that this complicates the situation, and then simply passes a lot of parameters.

So, after someone can help me figure out if I need to get / set the identifier and whether I should pass this value back to my interface. My second question is what about updates? Suppose that the end user finds a ticket, so on my interface I return some data about the tickets, and someone wants to update, tell me the description and the date. When I “Submit” these changes, should I just create a ticket object, set all the values ​​of the get / set property and this? Or should I just pass in the ID number and all the parameters to my BLL and let it handle it all?

Hope this all makes sense!

Thanks a lot guys!

+4
source share
6 answers

The answer is that it depends on the Framework or library you are using.

Not all BLLs just let you say Ticket t = new Ticket() , you might have to use t = b.CreateTicket() or something else. The identifier may be a temporary value or just null / 0 until it is stored.

In the second part of your question:

If you want to renew a ticket, you certainly will not create a new Ticket. You are updating an existing object.

Perhaps you should clarify or re-ask the question in the light of a particular library or technology.

+1
source

Normally I would use a specific key value (i.e. -1) as the default unsaved identifier. Then it will be transferred upward to the appropriate database level, which would save this object and update the identifier and return it if necessary (otherwise, if necessary, update the end-client request). I often have a default value for the default value for building an object.

In some previous projects, I used Guid keys as keys that can be generated on the client / server server, without the need to create a database to generate the keys (and then update the foreign keys to the parent objects). This can save a lot of time in terms of SQL execution, as it can be easily packaged). Guid crest can be used to create keys faster if necessary. However, this may not be an option if you need incremental keys.

This may vary depending on the structure / technology / infrastructure ...

+1
source

Use NHibernate or some other decent O / R Mapper and you won’t even have this problem. The property can be read-only and set by ORM itself before or immediately after insertion. If you do not do this manually, you can do it read-only and use a small number of reflections to set the identifier from the DAL, when necessary, without breaking encapsulation.

As an aside, why are you passing a BLL object? Shouldn't the entity itself implement its own business logic? What objects need to do. Otherwise, you should simply use strongly typed datasets. It looks like you are doing an “anemic domain model” which is bad:

http://martinfowler.com/bliki/AnemicDomainModel.html

0
source

Perhaps this ad will help you:

  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() {} } 
0
source

You can try something like this. The code is not perfect, but it will give you an idea. Sorry, I'm trying to do it faster than I should, so it's very rude.

 // 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 
0
source

A few points:

1 - Hungarian notation - Yuoo 1985. :)

2 - You reinvent the wheel here. There are many good ORM frameworks that do a great job with persistence and let you write your own domain.

3 - Good, so if you CANNOT use an ORM framework such as NHibernate or, God forbid, the Entity Framework, then I would suggest you stick to one of the standard patterns that use ORM frameworks, such as ActiveRecord or DataMapper . Yes, you need to assign an Identity Field after saving the new object. Martin Fowler’s ActiveRecord and DataMapper templates use the "insert" method to save new objects to the database. Other ORM structures, such as Rails, a similar method, use save and the new object can tell if it was saved by calling an interface such as new_record. which returns TRUE until "save" or "insert" is called. Until one of these methods is called, the identifier field is usually 0 or -1 by default, both invalid PKIDs. Inside "insert" or "save", the new id field is retrieved and assigned to the id field of the new object.

0
source

All Articles