首先我创建了一个变量值函数
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION GetPY
(
@str NVARCHAR(4000)
)
RETURNS NVARCHAR(4000)
AS
BEGIN
DECLARE @word NCHAR(1),@PY NVARCHAR(4000)
SET @PY=''
WHILE len(@str)>0
BEGIN
SET @word=left(@str,1)
SET @PY=@PY+(CASE WHEN unicode(@word) BETWEEN 19968 AND 19968+20901
THEN (SELECT TOP 1 PY FROM (
SELECT 'A' AS PY,N'驁' AS word
UNION ALL SELECT 'B',N'簿'
UNION ALL SELECT 'C',N'錯'
UNION ALL SELECT 'D',N'鵽'
UNION ALL SELECT 'E',N'樲'
UNION ALL SELECT 'F',N'鰒'
UNION ALL SELECT 'G',N'腂'
UNION ALL SELECT 'H',N'夻'
UNION ALL SELECT 'J',N'攈'
UNION ALL SELECT 'K',N'穒'
UNION ALL SELECT 'L',N'鱳'
UNION ALL SELECT 'M',N'旀'
UNION ALL SELECT 'N',N'桛'
UNION ALL SELECT 'O',N'漚'
UNION ALL SELECT 'P',N'曝'
UNION ALL SELECT 'Q',N'囕'
UNION ALL SELECT 'R',N'鶸'
UNION ALL SELECT 'S',N'蜶'
UNION ALL SELECT 'T',N'籜'
UNION ALL SELECT 'W',N'鶩'
UNION ALL SELECT 'X',N'鑂'
UNION ALL SELECT 'Y',N'韻'
UNION ALL SELECT 'Z',N'咗'
) T
WHERE word>=@word COLLATE Chinese_PRC_CS_AS_KS_WS
ORDER BY PY ASC) ELSE @word END)
SET @str=right(@str,len(@str)-1)
END
RETURN @PY
END
然后把这个函数更新到edmx,在模型浏览器中的存储过程能看到GetPY这个函数,但是在函数导入的时候,却找不到这个函数,错误提示为:无法为可编写的函数创建函数导入。于是我就用XML的形式打开了edmx把,可编写的(IsComposable)属性改成FALSE,错误提示:无法撰写的函数不得声明返回类型。
我的最终目的就是想写一个这样的表达式:
var str = "JS";
DBEntities db = new DBEntities();
var list = db.Users.Where(t => db.GetPY(t.Name).Contains(str)).ToList();
根据名字的首字母查询用户
等待高手解答!
sql里面可以用存储过程,将函数改为存储过程,在编程中用函数的很少,个人建议这样做,返回的数据再用linq查询。
可以用这样的方式调用:
using (var db=new EFTest())
{
var str = "JS";
var query = db.Database.SqlQuery<string>("select dbo.GetPY({0})", str).FirstOrDefault();
Console.WriteLine(query);
var list = db.Users
.Where(t => query.Contains(t.Name))
.ToList();
if (list != null)
{
Console.WriteLine(list.Count);
}
}
DEMO完整代码:
public class EFTest:DbContext
{
public DbSet<Users> Users { get; set; }
public EFTest() :
base("server=.;user id=sa;password=asdf;Initial Catalog=EFTest")
{
if (!this.Database.Exists())
{
this.Database.Create();
}
}
}
public class Users
{
[Key]
public int UserId { get; set; }
public string Name { get; set; }
}
public class EFFuncTest
{
public static void Test()
{
using (var db=new EFTest())
{
var str = "JS";
var query = db.Database.SqlQuery<string>("select dbo.GetPY({0})", str).FirstOrDefault();
Console.WriteLine(query);
var list = db.Users
.Where(t => query.Contains(t.Name))
.ToList();
if (list != null)
{
Console.WriteLine(list.Count);
}
}
}
}
调用:
static void Main(string[] args)
{
EFFuncTest.Test();
Console.Read();
}