0

Possible Duplicate:
LINQ Single vs First

Im new to Linq and want to learn it the best way, I have here 2 working update events for linq, thay do the same, but what way is the best and do i need to add something to make it better !?

Solution 1

Protected Sub Button2_Click(sender As Object, e As System.EventArgs) Handles Button2.Click
    Using db As New ThedatabaseconnectionDataContext()
        Try
            Dim TheUpdateID = DirectCast(FindControl("Textbox5"), TextBox).Text
            Dim getEditing As testtable = (From c In db.testtables Where c.test_id = TheUpdateID Select c).FirstOrDefault()
            If getEditing IsNot Nothing Then
                getEditing.test_cat = DirectCast(FindControl("Textbox1"), TextBox).Text
                getEditing.test_info = DirectCast(FindControl("Textbox2"), TextBox).Text
                getEditing.test_number = DirectCast(FindControl("Textbox3"), TextBox).Text
                getEditing.test_datetime = DirectCast(FindControl("Textbox4"), TextBox).Text
                db.SubmitChanges()
                'textBox1.Text = "Contact updated."
            End If
        Catch ex As Exception
            'Me.lblMsg.Text = ex.Message
        End Try
    End Using
End Sub

Solution 2

Protected Sub Button2_Click(sender As Object, e As System.EventArgs) Handles Button2.Click
    Using db As New ThedatabaseconnectionDataContext()
        Try
            Dim tbltest As Table(Of testtable) = db.GetTable(Of testtable)()
            Dim TheUpdateID = DirectCast(FindControl("Textbox5"), TextBox).Text
            Dim getEditing As testtable = tbltest.Single(Function(c) c.test_id = TheUpdateID)
            If getEditing IsNot Nothing Then
                getEditing.test_cat = DirectCast(FindControl("Textbox1"), TextBox).Text
                getEditing.test_info = DirectCast(FindControl("Textbox2"), TextBox).Text
                getEditing.test_number = DirectCast(FindControl("Textbox3"), TextBox).Text
                getEditing.test_datetime = DirectCast(FindControl("Textbox4"), TextBox).Text
                db.SubmitChanges()
                'textBox1.Text = "Contact updated."
            End If
        Catch ex As Exception
            'Me.lblMsg.Text = ex.Message
        End Try
    End Using
End Sub
Community
  • 1
  • 1
Thomas BP
  • 1,187
  • 3
  • 26
  • 62
  • @KirkBroadhurst not really a duplicate imo (of the linked question anyway) this is asking about which to use in which scenarios, the one you linked is asking which is more efficient for a single record – Manatherin Sep 24 '12 at 11:09

2 Answers2

4

First off, you should be able to write your first or default as

Dim getEditing As testtable = tbltest.FirstOrDefault(Function(c) c.test_id = TheUpdateID)

Untested but more to point out that first or default handles lambdas

As for which to use, it depends on your data. To break down what happens

Single - Expects exactly one match, A exception is thrown if no results are found OR multiple results are found

SingleOrDefault - Expects 0 or 1 match. A exception is thrown if multiple matches are found

First - Expects 1 or many match. Exception is thrown if no matches are found. Any results after the first result are ignored.

FirstOrDefault - handles 0, 1 or multiple matches. Any results after the first result are ignored.

If you are picking based on a ID from a listbox (I.e. it's unique and is definatly in the database) then single is a safe choice.

If the user is entering a ID (again unique) that may or may not be in the DB single or default is safe.

If searching based on a possible duplicate value, like surname, then first or firstordefault is what you should use depending if it is guaranteed to exist in the database or not.

Personally, regardless of the data, I would stick to either first or firstordefault as it handles more scenarios.

Community
  • 1
  • 1
Manatherin
  • 4,169
  • 5
  • 36
  • 52
  • Maybe an addition: 'FirstOrDefault - handles 0, 1 or multiple matches' - *but ignores anything after the first match* – Hans Kesting Sep 24 '12 at 10:20
  • @HansKesting Good point, have amended my answer – Manatherin Sep 24 '12 at 10:22
  • Great answer......Just an add, if i have this that u recoment........Dim tbltest As Table(Of testtable) = db.GetTable(Of testtable)() Dim TheUpdateID = DirectCast(FindControl("Textbox5"), TextBox).Text Dim getEditing As testtable = tbltest.FirstOrDefault(Function(c) c.test_id = TheUpdateID) How do i use INNER if my table is names testtable and maintable and i want to get the info from maintable, where main_id = test_id !? – Thomas BP Sep 24 '12 at 13:41
  • @ThomasBøgPetersen I'm not sure I understand what you mean – Manatherin Sep 24 '12 at 15:05
  • Hej Manatherin, i mean how do i make the (in this case) Dim tdltest if i have this old sql query thats getting info from 2 tables..... Dim cmd As New SqlCommand("SELECT Groups.Name FROM Roles INNER JOIN Groups ON Roles.GroupID = Groups.GroupID INNER JOIN Users ON Roles.UserID = Users.UserID AND Users.Username=@UserName", conn) – Thomas BP Sep 24 '12 at 15:51
  • @ThomasBøgPetersen in general I'd say you should query the user and go through the relations, e.g get the user, call the .Groups, then you could do a select many to get the group names like .Groups.SelectMany(x => x.Roles.select(y => y.Name)), None of this has been tested and probably won't compile but just to give you a idea. Alternatively, you could call a stored procedure or execute SQL from entity framework. You can join in LINQ but I try not to use that feature so someone else may be able to help you more if you ask it as a seperate question. – Manatherin Sep 25 '12 at 07:24
0

Where to even start on this one...

For a start, I know this is likely a test project, so apologies if you're already doing this, but please make sure you're using acceptable data tier hierarchies - your DBML should be in a separate project from your Presentation layer.

But, to the question in hand. My preferred way of doing this is getting the data object and updating it on an object level. Such as (pseudo code / I'm a C# kinda guy!):

private MyObject object;

protected void Page_Load(object sender, EventArgs e)
{
    // Select usually be ID
    object = DataLayer.GetObject();

    if(!IsPostBack)
    {
         // Load object details for editing into presentation layer
         TextboxObjectName.Text = object.Name;
    }
}

protected void Button_Click(object sender, EventArgs e)
{
     // Button click event - update object and send it to database
     object.Name = TextboxObjectName.Text;

     DataLayer.UpdateObject(object);
}

This makes use of object tracking, and the Daya Layer can then look like this:

function void UpdateObject(MyObject obj)
{
    using (TestDataContext db = new TestDataContext ())
    {

       db.MyObjects.Attach(obj);

       db.Refresh(RefreshMode.KeepCurrentValues, obj);

       db.SubmitChanges();
    }
}
Chris Dixon
  • 9,147
  • 5
  • 36
  • 68
  • Is the MyObject on the same page or on a class file !? Where do u point out what ID to update !? – Thomas BP Sep 24 '12 at 09:53
  • MyObject is the automatically generated class that your DBML will generate. Say, if your table was named "Files", then you'll have automatically generated class called "File" in which will be tracked by Entity Framework. The ID to select the object can be seen in the Page_Load comment. – Chris Dixon Sep 24 '12 at 09:57