2008-11-13 42 views
12

Tôi đang sử dụng LINQ to SQL cho một ứng dụng truy vấn cơ sở dữ liệu cũ. Tôi cần gọi thủ tục lưu sẵn, chọn một giá trị số nguyên duy nhất. Thay đổi thủ tục lưu sẵn không phải là một tùy chọn.LINQ-to-SQL: Thủ tục lưu trữ trả về một giá trị vô hướng đơn?

Các nhà thiết kế tạo ra một phương pháp với chữ ký này:

private ISingleResult<sp_xal_seqnoResult> NextRowNumber([Parameter(DbType="Int")] System.Nullable<int> increment, [Parameter(DbType="Char(3)")] string dataset) 

Tôi muốn các kiểu trả về là int. Làm thế nào để làm điều này bằng cách sử dụng LINQ-to-SQL?

Trả lời

13

Điều này sẽ tầm thường với hàm vô hướng (UDF) chứ không phải là SP. Tuy nhiên, nó sẽ làm việc dễ dàng đủ - mặc dù nếu SP là phức tạp (tức là FMT_ONLY không thể kiểm tra nó 100%) thì bạn có thể cần phải "giúp" nó ...

Đây là một số dbml mà tôi tạo ra từ một cách đơn giản SP trả về một số nguyên; bạn có thể chỉnh sửa các dbml qua "mở biên tập với ... xml):.

<Function Name="dbo.foo" Method="foo"> 
    <Parameter Name="inc" Type="System.Int32" DbType="Int" /> 
    <Parameter Name="dataset" Type="System.String" DbType="VarChar(20)" /> 
    <Return Type="System.Int32" /> 
</Function> 

(lưu ý bạn rõ ràng là cần phải tinh chỉnh tên và dữ liệu loại)

Và đây là tạo ra C#:

[Function(Name="dbo.foo")] 
public int foo([Parameter(DbType="Int")] System.Nullable<int> inc, [Parameter(DbType="VarChar(20)")] string dataset) 
{ 
    IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), inc, dataset); 
    return ((int)(result.ReturnValue)); 
} 

Nếu SP hiện tại của bạn sử dụng SELECT (thay vì RETURN), thì DBML sẽ cần phản ánh điều này bằng cách ẩn chi tiết triển khai và cung cấp trình bao bọc công khai trong một phần lớp, ví dụ:

<Function Name="dbo.foo" Method="FooPrivate" AccessModifier="Private"> 
    <Parameter Name="inc" Type="System.Int32" DbType="Int" /> 
    <Parameter Name="dataset" Type="System.String" DbType="VarChar(20)" /> 
    <ElementType Name="fooResult" AccessModifier="Internal"> 
     <Column Name="value" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" /> 
    </ElementType> 
</Function> 

Ở trên mô tả SP trả về một bảng đơn với một cột đơn; nhưng tôi đã thực hiện các SP "tin" vào dữ liệu ngữ cảnh, và kết quả kiểu "nội bộ" để lắp ráp (giấu nó):

[Function(Name="dbo.foo")] 
private ISingleResult<fooResult> FooPrivate(
    [Parameter(DbType="Int")] System.Nullable<int> inc, 
    [Parameter(DbType="VarChar(20)")] string dataset) 
{ 
    IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), inc, dataset); 
    return ((ISingleResult<fooResult>)(result.ReturnValue)); 
} 

Bây giờ trong tập tin lớp học của riêng tôi tôi có thể thêm một lớp học phần mới (một cs tập tin mới) trong không gian tên đúng, đó cho thấy nhiều phương pháp thuận tiện hơn:

namespace MyNamespace { 
    partial class MyDataContext 
    { 
     public int Foo(int? inc, string dataSet) 
     { 
      return FooPrivate(inc, dataSet).Single().value; 
     } 
    } 
} 

(không gian tên và tên bối cảnh cần phải được giống như các dữ liệu ngữ cảnh thực tế). Điều này cho biết thêm một phương pháp công cộng mà ẩn các chi tiết grungy từ người gọi.

Đừng chỉnh sửa tệp designer.cs trực tiếp; thay đổi của bạn sẽ bị mất. Chỉ chỉnh sửa các lớp dbml hoặc một phần.

+0

Chính xác những gì tôi đang tìm kiếm. Cảm ơn. – driis

+0

@driss - nếu bạn gặp vấn đề với SELECT, hãy cho tôi biết –

+0

Tôi đã sử dụng kỹ thuật tương tự trong dự án của tôi trước đó. Nó hoạt động tuyệt vời .. Cho đến khi bạn chỉnh sửa DBML của bạn trong trình soạn thảo bằng cách nào đó. Tất cả thay đổi của bạn sẽ bị ghi đè. Tôi đã từng giữ một tệp xml riêng biệt bất cứ khi nào tôi thay đổi thủ công, nhưng tôi hy vọng có một cách tốt hơn bằng cách nào đó. –

5

RETURN @VALUE làm tuyên bố cuối cùng của proc.

thì nó sẽ tự động phát hiện loại int, chuỗi, bool, v.v ... và tạo phương thức trình bao bọc phù hợp.

+0

Điều này phù hợp với tôi. Cảm ơn! –

+1

+1 Giá trị trả về phải đến từ biến vô hướng nên 'QUAY LẠI CHỌN COUNT (*) TỪ bảng' và 1RETURN SELECT @Value = COUNT (*) TỪ bảng 1 sẽ không hoạt động nhưng 'RETURN @ Value' sẽ. Ngoài ra, MS SQL/LINQ to SQL dường như không hỗ trợ các kiểu trả về tinyint/byte. – Trisped

0

Nếu bạn đang sử dụng tập tin XSD Visual Studio trong một LINQ to SQL lớp dự án, chắc chắn bạn:

  1. Nhấp chuột phải vào các thủ tục lưu trữ hoặc gọi hàm trong Adaptor.
  2. Chọn Properties
  3. Thay đổi Execute Mode để vô hướng

Điều đó sẽ làm cho bộ chuyển đổi của bạn loại chức năng quay trở lại "đối tượng". Sau đó bạn cần phải đúc nó vào int hoặc chuỗi, hoặc bất kỳ loại nó nên được.

Các vấn đề liên quan