2012-10-19 47 views
9

Tôi có một bảng có định dạng sau.Chuỗi tạo thành Ngày giờ trong LINQ

PID  ID  Label  Value 
------------------------------------------ 
1  1  First Name Jenna 
1  2  DOB   10/12/1980 

tôi cần phải lấy tất cả PID nơi First name bắt đầu với J và tháng DOB là 10.

trong mã của tôi, tôi lấy những trong DataTable trong C# và sau đó cố gắng sử dụng LINQ để lấy kết quả tôi muốn. Đây chỉ là một ví dụ. Những Nhãn này có thể là bất kỳ điều gì người dùng định nghĩa.

sử dụng LINQ Tôi có thể truy xuất tất cả các PID trong đó Tên bắt đầu bằng J, nhưng mỗi khi tôi cố gắng Truyền giá trị cho DOB, tôi nhận được lỗi không hợp lệ. Tôi không thể thay đổi kiểu cột trong cơ sở dữ liệu vì Giá trị có thể chứa bất kỳ loại thông tin nào.

Đây là một đoạn mã của tôi. Tôi mới đến LINQ, và vẫn cố gắng tìm ra nó.

var resultQuery = from r in query.AsEnumerable() 
where (r.Field<string>("Label") == Label && 
r.Field<DateTime>("Value").Month == 10) 
select r.Field<int>("PID"); 
+0

giá trị DateTime của "Jenna" là gì? Tôi không chắc rằng điều này là khả thi. – Bobson

Trả lời

3

Vì không phải tất cả các mục trong cột Giá trị của bảng đều có thể chuyển đổi thành DateTime, những gì bạn sẽ gặp phải khi chuyển đổi không hợp lệ. Bạn có thể thêm vào một mệnh đề đầu tiên kiểm tra xem giá trị có phải là DateTime và chỉ khi đó là, chuyển đổi nó và kiểm tra thuộc tính .Month.

DateTime d; 
var resultQuery = from r in query.AsEnumerable() 
        where (r.Field<string>("Label") == Label && 
         DateTime.TryParse(r.Field<string>("Value"), out d) && 
         d.Month == 10) 
        select r.Field<int>("PID"); 

Để có khả năng cải thiện khả năng đọc, bạn cũng có thể trích xuất này ra thành một phương pháp riêng biệt:

var resultQuery = from r in query.AsEnumerable() 
        let d = TryGetDate(r.Field<string>("Value")) 
        where (r.Field<string>("Label") == Label && 
         d != null && 
         d.Month == 10) 
        select r.Field<int>("PID"); 

private DateTime? TryGetDate(string value) 
{ 
    DateTime d; 
    return DateTime.TryParse(value, out d) ? d : default(DateTime?); 
} 
+2

Vì lợi ích của khả năng đọc và "đúng đắn", tôi tin rằng sẽ tốt hơn nếu đặt logic ngày trong một phương thức riêng biệt (DateTime? TryGetDate (giá trị chuỗi)) và trả về giá trị rỗng nếu không phân tích ... – ioctlLR

+0

Cảm ơn cả hai . Nếu tôi chỉ chạy truy vấn theo cách goric được đề xuất trên chính nó thì nó không bị lỗi, nhưng nếu tôi đang cố gắng chuyển đổi resultquery thành List và nó không thành công. Nếu tôi lấy ra .Month == 10, Danh sách của tôi hoạt động tốt. PID = resultQuery.ToList(); Trong trường hợp PID được định nghĩa ở loại Danh sách user1760153

+0

Không chỉ vậy, nhưng mã của bạn, như sẽ không hoạt động. Thậm chí nếu bạn có thể phân tích cú pháp chuỗi thành một ngày, bạn không thể chỉ * truyền * nó vào một ngày, đó là những gì bạn đang làm ở đây. – Servy

2

Bạn sẽ kết thúc lọc trong bộ nhớ mà không phải là rất hiệu quả.

Vì vậy, đầu tiên chọn dữ liệu của bạn

var data= from r in query.AsEnumerable(); 

Sau đó lọc trên các dữ liệu

var filtered = from item in data 
       where item.Label == "Label" 
       && Convert.ToDateTime(item.DOB).Month == 10 
       select item.PID; 
Các vấn đề liên quan