LINQ to Entities 中,有些断言能对内存实体使用,但是发到数据库端可能因无法解析而抛出异常,需要特别注意。示例如下:
s.IsNullOrWhiteSpace(), s.IsNullOrEmpty, s.IsEmpty()(这些方法都属于自定义的扩展方法,无法被EF直接解析为SQL语句)
如 a => a.FullName.IsNullOrWhiteSpace() 可以改写为: a => a.FullName != null && a.FullName.Length > 0
[TestMethod]
public void DataSourceGetOneTest()
{
string host = "localHost";
IList<string> IpAddress = EnvironmentEx.GetIpAddress();
ServerContext sc = this.CreateServerContext();
using (EdmWcfService edm = sc.CreateEdm<EdmWcfService>(Dbs.His))
{
// a => string.Equals(a.Name, host, StringComparison.CurrentCultureIgnoreCase不能用于数据库端,否则报下面错误:
// System.ArgumentException:“为方法“Boolean Equals(System.String, System.String, System.StringComparison)”的调用提供的参数的数量不正确”
// var dto = edm.WcfServers.FirstOrDefault(a => string.Equals(a.Name, host, StringComparison.CurrentCultureIgnoreCase));
// 如下用法是正确的:
var dto = edm.WcfServers.FirstOrDefault(a => (a.Name != null && a.Name.Equals(host, StringComparison.CurrentCultureIgnoreCase))
|| (a.Name != null && a.FullName.Equals(host, StringComparison.CurrentCultureIgnoreCase)));
// 下面写法也会报错如下:
// LINQ to Entities does not recognize the method 'Boolean StartsWith(System.String, System.StringComparison)' method, and this method cannot be translated into a store expression.
//dto = edm.WcfServers.FirstOrDefault(a => (a.Name != null && a.Name.StartsWith(host, StringComparison.CurrentCultureIgnoreCase))
// || (a.Name != null && a.FullName.StartsWith(host, StringComparison.CurrentCultureIgnoreCase)));
// 如下用法是正确的:
dto = edm.WcfServers.FirstOrDefault(a => (a.Name != null && a.Name.ToUpper().StartsWith(host.ToUpper()))
|| (a.Name != null && a.FullName.ToUpper().StartsWith(host.ToUpper())));
int serverId = (dto != null) ? dto.ServerId : -1;
Assert.IsTrue(serverId > 0);
}
}
其次,ORACLE数据库中空字符串被视为NULL处理,因此数据库SQL函数中字段值为' '(空格)的被 RTRIM(LRTRIM(a.Name)) 调用后结果并非空字符串,而是NULL。所以需要注意:
[TestMethod()]
public void TestEdmQuery()
{
using (ServerContext sc = WcfServiceHelper.CreateServerContext(ClientContext.Instance))
{
using (EdmConfig edm = sc.CreateEdm<EdmConfig>(Dbs.His))
{
var query = edm.EntityPickers.Where(a => a.UseCaseKey != null && a.UseCaseKey.Trim() == null);
string tracestring = query.ToTraceString();
Debug.Print(tracestring);
IList<DtoEntityPicker> ret = query.ToList();
}
}
}