2011-12-06 29 views
8

Tôi đang phân tích cú pháp XML (LINQ thành XML) và tôi đang sử dụng một kiểu rỗng (int?decimal?) trong trường hợp phần tử/thuộc tính trống. Tuy nhiên, khi xây dựng bộ sưu tập của tôi để vượt qua DB (Sử dụng TVP), tôi không biết cách xử lý các trường hợp giá trị thực sự là rỗng. Tôi không thể vượt qua một null vào SqlDataRecord SetInt32 hoặc SetDecimal và tôi không muốn thiết lập để không .... Tôi thực sự muốn nó được null.Làm thế nào để bạn xử lý kiểu Nullable với SqlDataRecord

Cho tôi biết không bị quá tải cho int?

Đếm dưới đây là một loại nullable (int? Đếm)

SqlDataRecord rec = new SqlDataRecord(
       new SqlMetaData("Name", SqlDbType.VarChar, 50), 
       new SqlMetaData("Type", SqlDbType.VarChar, 50), 
       new SqlMetaData("Count", SqlDbType.Int)); 

    rec.SetString(0, dm.Name); 
    rec.SetString(1, dm.Type); 
    rec.SetString(2, dm.Count); 

Bất kỳ ý tưởng làm thế nào để xử lý việc này mà không đi không (duy trì null)?

Trả lời

10

phương pháp mở rộng:

static class SqlDataRecordExtensions 
{ 
    static void SetNullableInt32(this SqlDataRecord rec, int index, Int32? value) 
    { 
     if (value.HasValue) 
      rec.SetInt32(index, value.GetValueOrDefault()); 
     else 
      rec.SetDBNull(index); 
    } 
} 

hay, sử dụng SetSqlInt32 theo đề nghị của D Stanley:

static class SqlDataRecordExtensions 
{ 
    static void SetNullableInt32(this SqlDataRecord rec, int index, Int32? value) 
    { 
     rec.SetSqlInt32(index, value.HasValue ? value.GetValueOrDefault() : SqlInt32.Null); 
     //          ^^^^^^^^^^^^^^^^^^^^^^^^^ 
     //          You can leave out the cast to (SqlInt32), 
     //          because the conversion is implicit 
    } 
} 

Note, 9 tháng 12 năm 2013: Quay trở lại với câu trả lời này vì một lời nhận xét , Tôi nhận thấy một cơ hội nhỏ để cải thiện, dựa trên loạt bài của Eric Lippert về các tối ưu hóa vi mô có thể vô hiệu hóa, có thể được tìm thấy tại http://ericlippert.com/2012/12/20/nullable-micro-optimizations-part-one/.

Tóm lại, trong khi thuộc tính Value yêu cầu ít đánh máy hơn và do đó được cho là tối ưu hơn cho lập trình viên, nó phải ném ngoại lệ nếu HasValue là sai. Mặt khác, phương thức GetValueOrDefault() là truy cập trường đơn giản. Bởi vì điều này, GetValueOrDefault() yêu cầu ít hướng dẫn hơn và có nhiều khả năng được gạch chân hơn, do đó, nó tối ưu hơn cho trình biên dịch và bộ xử lý.

+0

+1, rất đẹp .. –

+0

SetValue (thứ tự, đối tượng) xử lý các giá trị null và null với một chút chi phí cho loại và kiểm tra độ dài giá trị. Sự khác biệt hiệu suất có thể không đáng chú ý. –

+0

@RichardCollette Cảm ơn bạn đã bình luận; Tôi không nghĩ về điều đó. Tôi nghi ngờ bạn đúng rằng sự khác biệt hiệu suất có lẽ là không đáng kể đối với hầu hết các ứng dụng. Mặc dù vậy, tôi có khuynh hướng thích gõ mạnh hơn vào nền tảng triết học. Nhận xét của bạn cũng truyền cảm hứng cho tôi để thêm một tối ưu hóa nhỏ mà tôi không nghĩ đến hai năm trước. – phoog

3

Tôi chưa bao giờ làm việc với SqlDataRecord, nhưng khi sử dụng DataTableDataRow, hoặc khi sử dụng các truy vấn tham số, tôi chỉ định null sử dụng DBNull.Value.

Với SqlDataRecord, có vẻ như bạn có thể sử dụng phương thức SetDBNull.

0

Nên sử dụng SetSqlInt32 thay vì SetString. Hãy thử

rec.SetSqlInt32(2, (dm.Count.HasValue ? new SqlInt32(dm.Count) : SqlInt32.Null)); 
+0

Điều đó sẽ phải 'rec.SetSqlInt32 (2, (dm.Count.HasValue? new SqlInt32 (dm.Count.Value): SqlInt32.Null));' – phoog

+0

Hơn nữa, khi tôi nhận ra khi chỉnh sửa câu trả lời của tôi, chuyển đổi ngầm từ int sang SqlInt32 có nghĩa là bạn có thể làm điều này: 'rec.SetSqlInt32 (2, dm.Count.HasValue? dm.Count.Value: SqlInt32.Null);' – phoog

0

// Ive thấy điều này để làm việc tốt nhất cho tôi khi kiểm tra hoặc đối phó với các loại nullable // trong ví dụ của tôi, tôi đang kiểm tra các giá trị được lưu trữ trong một String [] array

sqlcmdUpdateRecord.Parameters.AddWithValue("@strSomeValue", (strRecord[(int) 
DataFields.SomeDataField] as object) ?? DBNull.Value); 
Các vấn đề liên quan