場景再現
我需要查詢公司名稱包含給定字符串的公司,於是我寫了下面的測試小例子:
var condition = "測試"; var query = from b in db.Companies where (condition == null || condition == "") ? true : b.Name.Contains(condition) orderby b.CompID select new { CompID = b.CompID, Name = b.Name }; Console.WriteLine("All companies in the database:"); foreach (var item in query) { Console.WriteLine("ID:" + item.CompID + "\tName:" + item.Name); }
沒想到運行的時候出現如下異常:
異常信息:“p__linq__1 : String truncation: max=0, len=2, value='測試'”。
異常截圖:
在EF的映射關系中,我明明將Name一項設了最大長度是64:
public class CompanyMap : EntityTypeConfiguration<Company> { public CompanyMap() { ToTable("Companies"); HasKey(p => p.PKCompany); Property(p => p.Name).IsRequired().HasMaxLength(64).HasColumnName("Company"); Property(p => p.IsChecked).IsRequired(); } }
那為什么查詢的時候會說最大長度是0,而傳入的參數長度是2,超過了這個0呢?
問題方案
我嘗試把where部分的三元表達式前面去掉,直接使用contains判斷是沒問題的,於是我懷疑是三元表達式那個條件出問題了,而提示字符串最大長度是0,我想到可能是判斷空字符那個條件有問題,所以我提前處理了一下,把程序改成如下,然后繞過了這個異常:
var condition = "測試"; //... condition = (condition == null || condition == "") ? null : condition; var query = from b in db.Companies where condition == null ? true : b.Name.Contains(condition) orderby b.CompID select new { CompID = b.CompID, Name = b.Name };
如果條件為null或者為空字符"",那么都改成空null,這么改完以后程序就工作了。
我查找了不少資料,介紹的方案都不是太有用,這里記錄一下如果有遇到這個異常的同學可以試一下!
這里我也沒用LinqPad去測試翻譯的結果,這個難道是EF的一個bug?