我有一个非常大的问题,似乎无法在互联网上找到任何其他人有我的问题。我当然希望StackOverflow可以帮助我...使用存储过程与Linq到Sql有其他参数
我正在写一个ASP.NET MVC应用程序,并将Linq To Sql作为我的数据存储使用存储库概念。关于从视图中选择行,一切都很好。并捕捉非常基本的业务规则约束。但是,我在存储过程映射中遇到了删除,插入和更新中的问题。让我解释一下:
我们的DBA已经投入了大量的工作来将业务逻辑放入我们所有的存储过程中,这样我就不必担心我的问题了。当然,我做了基本的验证,但是他管理数据完整性和冲突日期约束等等。我面临的问题是所有存储过程(以及我的意思是所有)都有5个附加参数(插入6个)提供给我的信息。这个想法是,当某些事情中断时,我可以用数据库中的适当信息提示用户。
例如:
sp_AddCategory(
@userID INT,
@categoryName NVARCHAR(100),
@isActive BIT,
@errNumber INT OUTPUT,
@errMessage NVARCHAR(1000) OUTPUT,
@errDetailLogID INT OUTPUT,
@sqlErrNumber INT OUTPUT,
@sqlErrMessage NVARCHAR(1000) OUTPUT,
@newRowID INT OUTPUT)
从上述的存储过程,所述第一3个参数是用于“创建”的分类记录的唯一参数。其余参数仅用于告诉我在方法内发生了什么。如果业务规则在存储过程中被破坏,那么在业务规则被破坏时,他不会使用SQL'RAISEERROR'关键字。相反,他使用OUTPUT参数向我提供有关错误的信息。他为我们的数据库中的每个存储过程执行此操作,即使是更新和删除。所有'Get'调用都使用自定义视图完成。它们都经过了测试,并且我的想法是让我的工作更轻松,因为我不必添加业务逻辑来捕获所有各种场景以确保数据质量。
正如我所说,我正在使用Linq To Sql,而现在我面临着一个问题。问题是我的“Category”模型对象只有4个属性:CategoryID,CategoryName,UserId和IsActive。当我打开设计器开始映射插入的属性时,我意识到除非将它们添加到我的Model对象中,否则我没有(简单的)方法来解释附加参数。
理论上讲什么,我想这样做是这样的:
// note: Repository Methods
public void AddCategory(Category category)
{
_dbContext.Categories.InsertOnSubmit(category);
}
public void Save()
{
_dbContext.SubmitChanges();
}
然后从我的CategoryController类我只想做到以下几点:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(FormCollection collection)
{
var category = new Category();
try
{
UpdateModel(category); // simple validation here...
_repository.AddCategory(category);
_repository.Save(); // should get error here!!
return RedirectToAction("Index");
}
catch
{
// manage friendly messages here somehow... (??)
// ...
return View(category);
}
}
什么是使用管理的最佳方式Linq to Sql?我(个人)认为将所有这些附加属性添加到每个模型对象是有意义的...例如,'Get'不应该有错误,我不希望我的存储库方法返回一个获取调用的对象类型,但接受CUD调用的另一种类型的对象。
更新:我的解决方案! (2009年12月1日)
下面是我所做的解决我的问题。我摆脱了我所有存储库中的'Save()'方法。相反,我为每个存储库添加了一个'Update()'方法,并实际将数据提交给每个CUD(即Create/Update/Delete)调用的数据库。
我知道,每个存储过程具有相同的参数,所以我创建了一个类来保存它们:
public class MySprocArgs
{
private readonly string _methodName;
public int? Number;
public string Message;
public int? ErrorLogId;
public int? SqlErrorNumber;
public string SqlErrorMessage;
public int? NewRowId;
public MySprocArgs(string methodName)
{
if (string.IsNullOrEmpty(methodName))
throw new ArgumentNullException("methodName");
_methodName = methodName;
}
public string MethodName
{
get { return _methodName; }
}
}
我还创建了接受MySprocArgs在它的构造函数MySprocException:
public class MySprocException : ApplicationException
{
private readonly MySprocArgs _args;
public MySprocException(MySprocArgs args) : base(args.Message)
{
_args = args;
}
public int? ErrorNumber
{
get { return _args.Number; }
}
public string ErrorMessage
{
get { return _args.Message; }
}
public int? ErrorLogId
{
get { return _args.ErrorLogId; }
}
public int? SqlErrorNumber
{
get { return _args.SqlErrorNumber; }
}
public string SqlErrorMessage
{
get { return _args.SqlErrorMessage; }
}
}
现在,这里是所有的东西在一起......使用我在初始查询中开始的例子,这里是'AddCategory()'方法的样子:
public void AddCategory(Category category)
{
var args = new MySprocArgs("AddCategory");
var result = _dbContext.AddWidgetSproc(
category.CreatedByUserId,
category.Name,
category.IsActive,
ref args.Number, // <-- Notice use of 'args'
ref args.Message,
ref args.ErrorLogId,
ref args.SqlErrorNumber,
ref args.SqlErrorMessage,
ref args.NewRowId);
if (result == -1)
throw new MySprocException(args);
}
现在从我的控制,我只是做到以下几点:
[HandleError(ExceptionType = typeof(MySprocException), View = "SprocError")]
public class MyController : Controller
{
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Category category)
{
if (!ModelState.IsValid)
{
// manage friendly messages
return View(category);
}
_repository.AddCategory(category);
return RedirectToAction("Index");
}
}
的技巧来管理新MySprocException
是简单地使用的HandleError属性,将用户重定向到一个能理解MySprocException页面陷阱吧。
我希望这有助于某人。 :)
非常漂亮。感谢您的反馈。我现在正在修改一个想法,即创建一个全球性的“SprocResult”对象,这个对象将用于所有CUD调用,并按照您的建议手动管理它们。我在我的DataContext上创建了一个方法(使用部分类),它将保存如下所示的调用: context.CallSproc(SprocResult result,params SqlParameter [] args); 再次感谢。有时候,我只需要有人给我种一颗种子。 :)你已经做到了这一点......当我有工作的时候,我一定会用我的解决方案更新我的问题。 – Luc 2009-09-14 19:39:50
已解决!你的建议帮助我解决了我的问题。谢谢!这是我做的:创建一个带有“common”错误变量的SprocArgs类。所以context.AddCategory(...,ref args.ErrorNumber,ref args.ErrorMessage等)。对于我的存储库中的每个CUD方法,我都是逐个手动处理它们。如果一个sproc失败(即。(AddCategory(...)!= 0),那么我只需要抛出新的SprocException(args)。现在唯一要做的就是捕获我的模型对象的属性更改,以便'更新()“'Save()'上的任何脏模型对象谢谢!! – Luc 2009-09-14 21:08:01
@Luc:你可能会把你的解决方案放在你的问题的最后?在评论中,这很难破译,因为你无法格式化代码片段........谢谢! – 2009-09-14 21:34:29