public IEnumerable<T> ExecuteStoredProcedure<T>(params object[] parameters)
{
Type genericType = typeof(T);
string commandthing = genericType.Name.Replace("Result", "");
//_db is my Linq To Sql database
return _db.ExecuteQuery<T>(commandthing, parameters).AsEnumerable();
}
存储过程名为GetOrder,并且具有orderid的单个int参数。我这样称呼上述内容:
SqlParameter parm1 = new SqlParameter("@orderid", SqlDbType.Int);
parm1.Value = 123;
var results =
_session.ExecuteStoredProcedure<GetOrderResult>(parm1).Single();
我收到以下错误:查询参数不能是'System.Data.SqlClient.SqlParameter'的类型
思考?或者我只是遗漏了一些明显的东西?
更新:我正在努力使其尽可能通用...我当前的想法是,我将不得不做一些字符串技巧来创建ExecuteQuery文本和参数。
更新:在我的会话界面和我的Linq to Sql下面发布界面的实现...希望这将澄清我正在尝试做什么
public interface ISession : IDisposable
{
void CommitChanges();
void Delete<T>(Expression<Func<T, bool>> expression) where T : class;
void Delete<T>(T item) where T : class;
void DeleteAll<T>() where T : class;
T Single<T>(Expression<Func<T, bool>> expression) where T : class;
IQueryable<T> All<T>() where T : class;
void Add<T>(T item) where T : class;
void Add<T>(IEnumerable<T> items) where T : class;
void Update<T>(T item) where T : class;
IEnumerable<T> ExecuteStoredProcedure<T>(params object[] parameters);
}
public class LinqToSqlSession : ISession
{
public readonly Db _db;
public LinqToSqlSession()
{
_db = new Db(ConfigurationManager.ConnectionStrings[Environment.MachineName].ConnectionString);
}
public void CommitChanges()
{
_db.SubmitChanges();
}
/// <summary>
/// Gets the table provided by the type T and returns for querying
/// </summary>
private Table<T> GetTable<T>() where T : class
{
return _db.GetTable<T>();
}
public void Delete<T>(Expression<Func<T, bool>> expression) where T : class
{
var query = All<T>().Where(expression);
GetTable<T>().DeleteAllOnSubmit(query);
}
public void Delete<T>(T item) where T : class
{
GetTable<T>().DeleteOnSubmit(item);
}
public void DeleteAll<T>() where T : class
{
var query = All<T>();
GetTable<T>().DeleteAllOnSubmit(query);
}
public void Dispose()
{
_db.Dispose();
}
public T Single<T>(Expression<Func<T, bool>> expression) where T : class
{
return GetTable<T>().SingleOrDefault(expression);
}
public IEnumerable<T> ExecuteStoredProcedure<T>(params object[] parameters)
{
Type genericType = typeof(T);
string commandstring = genericType.Name.Replace("Result", "");
//_db is my Linq To Sql database
return _db.ExecuteQuery<T>(commandstring, parameters).AsEnumerable();
}
public IQueryable<T> All<T>() where T : class
{
return GetTable<T>().AsQueryable();
}
public void Add<T>(T item) where T : class
{
GetTable<T>().InsertOnSubmit(item);
}
public void Add<T>(IEnumerable<T> items) where T : class
{
GetTable<T>().InsertAllOnSubmit(items);
}
public void Update<T>(T item) where T : class
{
//nothing needed here
}
}
答案 0 :(得分:1)
这不是你应该如何使用Linq-to-SQL连接存储过程。您应该扩展DataContext
并改为使用ExecuteMethodCall
:
取自MSDN:
public partial class MyDataContext
{
[Function()]
public IEnumerable<Customer> CustomerById(
[Parameter(Name = "CustomerID", DbType = "NChar(5)")]
string customerID)
{
IExecuteResult result = this.ExecuteMethodCall(this,
((MethodInfo)(MethodInfo.GetCurrentMethod())),
customerID);
return (IEnumerable<Customer>)(result.ReturnValue);
}
}
如果你真的必须执行一个sproc作为查询(高度不推荐),那么你必须在命令前添加EXEC
,并且'don' t使用SqlParameter
,调用看起来像:
var results = context.ExecuteQuery<MyResult>("EXEC usp_MyProc {0}, {1}",
custID, custName);
(我会先注意,这不是一个SQL注入向量,因为Linq to SQL将花括号变成了参数化查询。)
答案 1 :(得分:1)
了解如何在linq中调用sprocs到sql
答案 2 :(得分:1)
有同样的问题。以下方法对我有用。
public interface IBusinessEntityRepository
{
.......
object CallStoredProcedure(string storedProcedureName, object[] parameters);
}
在我的linqtosql GenericLinqRepository中实现
public object CallStoredProcedure(string storedProcedureName, object[] parameters)
{
DataContext dataContext = GetCurrentDataContext();
MethodInfo method = dataContext.GetType().GetMethod(storedProcedureName);
return method.Invoke(dataContext, parameters);
}
答案 3 :(得分:0)
我确信有更好的方法可以做到这一点......但目前正在运作:
public IEnumerable<T> ExecuteStoredProcedure<T>(params object[] parameters)
{
Type genericType = typeof(T);
StringBuilder sb=new StringBuilder();
sb.Append("EXEC ");
sb.Append(genericType.Name.Replace("Result", " " ));
for (int i = 0; i < parameters.Count(); i++)
{
sb.Append("{" + i.ToString() + "} ");
}
string commandstring = sb.ToString();
return _db.ExecuteQuery<T>(commandstring, parameters);
}
它有点脆弱,因为你的参数必须以正确的顺序设置,而且它可能会冒犯某些......但它确实实现了目标。
答案 4 :(得分:0)
您可以改用:
新的SqlParameter {ParameterName =“UserID”,Value = txtuserid.Text}
System.7Data.SqlClient中的这个等价物:
SqlParameter [] param = new SqlParameter [2]; param [0] = new SqlParameter(“@ UserID”,txtuserid)