2015-06-12 19 views
7

Tôi có một tình huống mà tôi chỉ muốn sử dụng mệnh đề WHERE khi cần thiết, nếu không tôi chỉ muốn chạy truy vấn LINQ mà không cần mệnh đề WHERE.Làm thế nào tôi có thể tạo điều khoản where có điều kiện bằng cách sử dụng LINQ

Ví dụ:

nếu tên chuỗi = "";

var res = (from a in db.person 
      select new() { Name = a.FullName, DOB = a.DOB }).ToList(); 

nếu tên chuỗi = "satya";

var res = (from a in db.person 
      where a.person.contains(name) 
      select new() { Name = a.FullName, DOB = a.DOB }).ToList(); 

Tôi biết điều này, chúng tôi phải viết riêng 2 truy vấn riêng biệt, nhưng không viết các truy vấn riêng biệt, làm cách nào chúng ta có thể kết hợp chúng thành một truy vấn?

+1

'.toList()' phải là '.ToList()'. Nhưng sau đó một lần nữa, trừ khi bạn thực sự cần một danh sách có lẽ nó không nên có ở tất cả; liệt kê trực tiếp cắt ra việc tạo ra một danh sách chỉ để sau đó liệt kê nó. –

Trả lời

16

Bạn có thể làm:

var res = (from a in db.person 
      where name == "" || a.person.Contains(name) 
      select new { Name = a.FullName, DOB = a.DOB } 
     ).ToList(); 

Ngoài ra, ở đây sử dụng cú pháp thành thạo, bạn có thể xây dựng truy vấn của bạn và thực hiện nó một lần bạn đã hoàn tất:

var query = db.person.AsQueryable(); 

if(!String.IsNullOrEmpty(name)) { 
    query = query.Where(a => a.person.Contains(name)); 
} 

var result = query.Select(s => new { Name = s.FullName, DOB = s.DOB }) 
        .ToList(); 
+0

Cảm ơn bạn đã bình luận, Nhưng tôi nhận được Time Out Exception khi tôi đang sử dụng ToList(), vì nó có một số bản ghi crores. Trong khi nó được lấy hồ sơ tôi nhận được ngoại lệ, nhưng tôi đã không nhận được rằng ngoại lệ nếu tôi viết truy vấn trực tiếp bằng cách sử dụng Nếu khác truy vấn riêng biệt. –

+0

Thời gian chờ xảy ra do thời gian chờ kết nối đang duy trì kết nối trực tiếp với cơ sở dữ liệu, vì bạn đang tìm nạp loại IQueryable, tùy chọn sẽ tăng thời gian chờ kết nối, theo mặc định là 60 giây hoặc đưa dữ liệu vào bộ nhớ và xử lý , đó là những gì bạn đang làm trong các vòng lặp của bạn. Dù sao xử lý dữ liệu này cho mỗi cuộc gọi là điên –

0

Tôi nghĩ bạn có thể sử dụng mã đoạn 2 để có được kết quả tương tự với đoạn mã 1 thậm chí tên chứa chuỗi trống. Tại sao bạn nên tạo 2 mã khác nhau. Có phải vấn đề về hiệu suất không?

var res = (from a in db.person 
where a.person.contains(name) // if empty, it will return all list, just makes sure it's not null before 
select new(){Name=a.FullName,DOB=a.DOB}).toList(); 

tôi cố gắng này trên mẫu mã của tôi và nó hoạt động tốt

static void TestContains() 
     { 
      IList<CustomEntity> _a = new List<CustomEntity>(); 
      IList<CustomEntity> _b = new List<CustomEntity>(); 

      _a.Add(new CustomEntity { ID = 1, Code = "a", Description = "aaa" }); 
      _a.Add(new CustomEntity { ID = 2, Code = "c", Description = "c" }); 

      string name = string.Empty; 
      _b = _a.Where(a => a.Description.Contains(name)).ToList(); 

      foreach (CustomEntity temp in _b) 
      { 
       Console.WriteLine(temp.Description); 
      } 
     } 

Đây sẽ là kết quả

aaa 
c 
+0

Tôi thử điều này trong mã mẫu của tôi và nó hoạt động tốt. Bạn có nghĩa là "" trống, không phải là 'null' –

1

Tiếp theo nên làm việc, bạn có thể tinh chỉnh nó theo cách bạn muốn đạt được kết quả mong muốn. Chỉ phục vụ cho các điều kiện của chuỗi rỗng/null hoặc tên được chứa trong a.person, nghỉ ngơi tất cả sẽ dẫn đến null, mà chúng tôi lọc vào cuối

db.person.Select(a=>{ 
        if (String.IsEmptyOrNull(name) || 
          a.person.contains(name)) 
         return new {Name=a.FullName,DOB=a.DOB}; 
         else 
         return null; 
        } 
       ).Where(x=>x!=null).ToList() 

tạo nó trên một pad văn bản, có thể có nhỏ vấn đề cú pháp

Các vấn đề liên quan