tags:

views:

2047

answers:

6

My code for sql connection using linq is:

var query1 = from u in dc.Usage_Computers
          where u.DomainUser == s3
          select u; // selects all feilds from table

GridView1.DataSource = query1;
GridView1.DataBind();

I have a field called "Operation" in the table "Domainuser" which has values like "1, 2, 3". When I populate these values to data grid I wanted to convert them to meaningful values like if the value of Operation is 1 then display in datagrid as "logon", if 2 then "logoff" etc...

How do i assign values for them after retrieving from database?

A: 

I've done something similar using TemplateFields. Using an ASP:Label bound to the property and adding an OnPreRender event handler for the control. In the event handler for the control I translate the text based on it's current value and set the new value:

protected void label_OnPreRender( object sender, EventArgs e )
{
   Label l = (Label)sender;
   switch (l.Text) {
      case "1":
         l.Text = "Logon";
         break;
       ...
      default:
         break;
   }
}

If the form is in edit mode, you'll need to handle it differently. You'll also probably need to add handlers for Inserting and Updating to the View control you are using to translate the data supplied by the page into its database representation.

tvanfosson
A: 

I wanted a code for switch case for linq sql in datagrid. Not label.

Not sure how you would do this. Probably need a delegate to translate values from one representation to another and return a new anonymous type.
tvanfosson
+2  A: 

Use a template field in your gridview:

<asp:GridView ID="gvDomain" runat="server" OnRowDataBound="gvDomain_RowDataBound">
    <Columns>
        <asp:TemplateField>
             <HeaderTemplate>
                 Operation
             </HeaderTemplate>
             <ItemTemplate>
                 <asp:Label id="lblLogon" runat="server" />
             </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

Then use the gridviews RowDataBound event to discover the label and assign its text:

Protected Sub gvDomain_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gvStates.RowDataBound
    Dim lblLogon As Label = DirectCast(e.Row.FindControl("lblLogon"), Label)
    Dim drv As DataRowView = DirectCast(e.Row.DataItem, DataRowView)

    If lblLogon IsNot Nothing Then
        Select Case drv("Operation").ToString()
            Case "1" 
                lblLogon.Text = "Logon"
                Break
            Case "2"
                lblLogon.Text = "Logoff"
                Break
            //etc...
        End Select
    End If
End Sub
Brendan Kendrick
+1  A: 
static Func<int?, string> MapSqlIntToArbitraryLabel = (i =>
{
   // for performance, abstract this reference 
   //  dictionary out to a static property
   Dictionary<int, string> labels = new Dictionary<int, string>();
   labels.Add(1, "logon");
   labels.Add(2, "logoff");
   labels.Add(...);

   if (i == null) throw new ArgumentNullException();
   if (i < 1 || i > labels.Count) throw new ArgumentOutOfRangeException();

   return labels.Where(x => x.Key == i.Value)
                .Select(x.Value)
                .Single();
}

that return statement can also be expressed as:

return (from kvp in labels
        where kvp.Key == i.Value
        select kvp.Value).Single();

Then you can use call that function from your linq query like so:

var query1 = from u in dc.Usage_Computers 
             where u.DomainUser == s3 
             select {
                 Operation = MapSqlIntToArbitraryLabel(u.Operation)
                 // add other properties to this anonymous type as needed
             };

I've tried every suggested method of fooling Linq2Sql into running my code and this method is the only one that i've found that allows me to run code as part of a deferred-execution projection.

David Alpert
while i agree in general with the approach (+1), think it's a little overkill. A simple dictionary may suffice (and provide better performance). Also should initialise once only. Only other thing is consideration for making the translation method an extension method to the object.
Samuel Kim
Extension methods on the object were my first try, but i have found this approach generalizes well - i.e., from within MapSqlIntToArbitraryLabel() you could call a method that is not recognized by Linq2Sql and it appears to run without choking on the "no translation to sql" issue.
David Alpert
+5  A: 

This technique does not seem particularly applicable to your problem, but here it is anyway.

You can create a SQL case statement in LinqToSql by using the C# ? : operator.

var query1 =
  from u in dc.Usage_Computers
  where u.DomainUser == s3
  select new {usage = u, 
    operation =
      u.DomainUser.Operation == 1 ? "login" :
      u.DomainUser.Operation == 2 ? "logoff" :
      "something else"
  };
David B
Why people want the database to transform ints into label strings for them, I'll never know. Seems like a job for the webserver.
David B
Thanks David! Your method worked for me!
while the solution answers the question, I think it is a bad practice to sprinkle conversion logic like that. Such conversion logic should be centralized into a reusable class.
Samuel Kim
David, when given the opportunity to perform a simple conversion like this in either the web server or the database, you can consider which engine has the least load already, and do the conversion there. Often, there's more CPU available in the database server.
DOK
A: 

Thanks David..Your method worked for me!