문제

나에게는 매우 큰 문제가 있는데 인터넷에서 내 문제를 갖고 있는 사람을 찾을 수 없는 것 같습니다.StackOverflow가 나에게 도움이 되기를 바랍니다...

저는 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'에는 오류가 있어서는 안 되며 저장소 메서드가 Get 호출에 대해 한 유형의 개체를 반환하고 CUD 호출에 대해 다른 유형의 개체를 허용하는 것을 원하지 않습니다.

업데이트:나의 솔루션!(12월.2009년 1월 1일)

내 문제를 해결하기 위해 내가 한 일은 다음과 같습니다.모든 저장소에서 'Save()' 메소드를 제거했습니다.대신 각 저장소에 'Update()' 메서드를 추가하고 실제로 각 CUD의 데이터베이스에 데이터를 커밋했습니다.생성/업데이트/삭제) 통화를 합니다.

각 저장 프로시저에 동일한 매개변수가 있다는 것을 알았으므로 해당 매개변수를 보유할 클래스를 만들었습니다.

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을 이해하는 페이지로 사용자를 리디렉션하는 것입니다.

이것이 누군가에게 도움이 되기를 바랍니다.:)

도움이 되었습니까?

해결책

매개 변수가 데이터베이스의 어떤 테이블에도 유지되지 않기 때문에 LINQ 클래스에 출력 매개 변수를 추가할 수 없다고 생각합니다.

그러나 다음과 같은 방법으로 LINQ에서 출력 매개변수를 처리할 수 있습니다.

디자이너를 사용하여 .dbml에 호출하려는 저장 프로시저를 추가하세요.

코드에서 저장 프로시저 호출

 using (YourDataContext context = new YourDataContext())
 {
    Nullable<int> errNumber = null;
    String errMessage = null;
    Nullable<int> errDetailLogID = null;
    Nullable<int> sqlErrNumber = null;
    String sqlErrMessage = null;
    Nullable<int> newRowID = null;
    Nullable<int> userID = 23;
    Nullable<bool> isActive=true;

    context.YourAddStoredProcedure(userID, "New Category", isActive, ref errNumber, ref errMessage, ref errDetailLogID, ref sqlErrNumber, ref sqlErrMessage, ref newRowID);
 }

다른 팁

아직 시도하지는 않았지만 출력 매개 변수를 반환하는 저장된 절차에 대해 이야기하는이 기사를 살펴볼 수 있습니다.

http://weblogs.asp.net/scottgu/archive/2007/08/16/linq-to-sql-part-6-retrieving-data-using-procedures.aspx

기본적으로 저장된 절차를 LINQ로 SQL 디자이너로 드래그하면 작업을 수행해야합니다.

그만큼 dbContext.SubmitChanges(); 엔티티 프레임 워크에만 작동합니다. 저장, 업데이트 및 삭제는 단일 저장 프로 시저를 사용하거나 3 가지 다른 절차를 사용하여 작동합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top