Question

I am new to ASP.net dynamic data. I have a column in database (tracking ID) it requires to be generated in a pattern through code i.e "23041401" (the date and a 2 digit increment number). I have tried lot of things but need guidance to go in the right way. I have made a separate class for my "cases" table for setting the metadata etc.

/// <summary>
/// Summary description for formatting
/// </summary>

[ScaffoldTable(true)]
[DisplayName("Cases")]
[MetadataType(typeof(caseMetadata))]

public partial class @case 
{


}

public class caseMetadata
{
    [UIHint("datetelerik")]
    [DisplayFormat(DataFormatString = "{0:dd-MM-yyyy}")]
    [DisplayName("Start Date")]
    public object s_date { get; set; }

    [UIHint("datetelerik")]
    [DisplayFormat(DataFormatString = "{0:dd-MM-yyyy}")]
    [DisplayName("End Date")]
    public object e_date { get; set; }

    [UIHint("Multilinetext")]
    [DisplayName("Case Description")]
    public object case_desc { get; set; }

    [DisplayName("Amount")]
    public object amount { get; set; }

    [DisplayName("Invoices")]
    public object invoices { get; set; }

    [DisplayName("Logs")]
    public object cases_logs { get; set; }

    [ReadOnly(true)]
    [DisplayName("Tracking ID")]
    public object tracking_id {get; set;}

}

Here's the function I have so far for generating the ID.

public string GenerateId()
        {
        int case_id = 1;
        int t_id;
        SqlConnection con = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["hafee‌​z_enterprisesConnectionString"].ConnectionString);
        con.Open(); SqlCommand cmd = new SqlCommand("select max(case_id) as max from cases", con);
        SqlDataReader reader = cmd.ExecuteReader();
        while (reader.Read())
            {
            case_id = Convert.ToInt16(reader["max"].ToString());
            }
        t_id = Convert.ToInt32(DateTime.Now.ToString("ddMMyy") + (case_id + 1));
        return t_id.ToString();
        }
Was it helpful?

Solution

First, this is almost always a bad way of doing a database key. It requires a trip to the database to get a key, and in high-volume cases, you could still wind up with duplicates if two requests happen at the same time. It's usually best to use a natural key or an auto-increment if possible.

That said, if you don't have control over that, or it would be too difficult to refactor, and have to use this technique, then one way would be to intercept the object in the data context before it gets saved. You can loop through all changes and do "stuff" before the database calls are made. I've used this to set changed date, track the user, or log. Something like this might work in your case:

public class YourDbContext{

public override int SaveChanges()
{
     foreach (var entry in this.ChangeTracker.Entries())
     {
            var caseEntry = entry.Entity as @case;
            if (caseEntry != null)
            {

                if (entry.State == EntityState.Added)
                {
                    caseEntry.Id = GenerateId();                       
                }

            }
     }
     return base.SaveChanges();
}

}

I believe this would work with your dynamic data code (assuming you're using Entity Framework).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top