LINQ to SQL 对象模型

更新:November 2007

在 LINQ to SQL 中,用开发人员所用的编程语言表示的对象模型映射到关系数据库的数据模型。然后就会按照对象模型来执行对数据的操作。

在这种情况下,您无需向数据库发出数据库命令(例如,INSERT),而是在对象模型中更改值和执行方法。当您需要查询数据库或向其发送更改时,LINQ to SQL 会将您的请求转换成正确的 SQL 命令,然后将这些命令发送到数据库。

LINQ to SQL 对象模型

下表概括了 LINQ to SQL 对象模型中最基本的元素及其与关系数据模型中的元素的关系:

LINQ to SQL 对象模型

关系数据模型

实体类

类成员

关联

外键关系

方法

存储过程或函数

说明:

以下说明假定您已具备关系数据模型和规则方面的基础知识。

LINQ to SQL 实体类与数据库表

在 LINQ to SQL 中,数据库表由实体类表示。实体类与您可能创建的任何其他类相似,只不过对实体类进行批注的方法是使用将该类与数据库表关联的特殊信息。您需通过向类声明中添加自定义属性 (TableAttribute) 来进行这种批注,如下面的示例所示:

示例

<Table(Name:="Customers")> _
Public Class Customer
    Public CustomerID As String
    ' ...
    Public City As String
End Class
[Table(Name = "Customers")]
public class Customerzz
{
    public string CustomerID;
    // ...
    public string City;
}

只有声明为表的类(即实体类)的实例才能保存到数据库中。

有关更多信息,请参见基于属性的映射 (LINQ to SQL) 的“表属性”一节。

LINQ to SQL 类成员与数据库列

除了将类与表关联以外,您还需指定字段或属性来表示数据库列。为此,LINQ to SQL 定义了 ColumnAttribute 属性,如下面的示例所示:

示例

<Table(Name:="Customers")> _
Public Class Customer
    <Column(IsPrimaryKey:=True)> _
    Public CustomerID As String

    <Column()> _
    Public City As String
End Class
[Table(Name = "Customers")]
public class Customer
{
    [Column(IsPrimaryKey = true)]
    public string CustomerID;
    [Column]
    public string City;
}

只有映射到列的字段和属性才能持久保存到数据库中,从数据库中也只能检索这样的字段和属性。那些未声明为列的字段和属性被视为应用程序逻辑的瞬态部分。

ColumnAttribute 属性 (Attribute) 具有各种属性 (Property),您可以使用这些属性 (Property) 来自定义表示列的这些成员(例如,将某一成员指定为表示主键列)。有关更多信息,请参见基于属性的映射 (LINQ to SQL) 的“列属性”一节。

LINQ to SQL 关联与数据库外键关系

在 LINQ to SQL 中,数据库关联(如外键到主键关系)是通过应用 AssociationAttribute 属性表示的。在下面的代码段中,Order 类包含具有 AssociationAttribute 属性 (Attribute) 的 Customer 属性 (Property)。此属性 (Property) 及其属性 (Attribute) 为 Order 类提供了与 Customer 类的关系。

下面的代码示例显示了 Order 类中的 Customer 属性 (Property)。

示例

 <Association(Name:="FK_Orders_Customers", Storage:="_Customer", ThisKey:="CustomerID", IsForeignKey:=true)>  _
    Public Property Customer() As Customer
        Get
            Return Me._Customer.Entity
        End Get
        Set
            Dim previousValue As Customer = Me._Customer.Entity
            If (((previousValue Is value)  _
                        = false)  _
                        OrElse (Me._Customer.HasLoadedOrAssignedValue = false)) Then
                Me.SendPropertyChanging
                If ((previousValue Is Nothing)  _
                            = false) Then
                    Me._Customer.Entity = Nothing
                    previousValue.Orders.Remove(Me)
                End If
                Me._Customer.Entity = value
                If ((value Is Nothing)  _
                            = false) Then
                    value.Orders.Add(Me)
                    Me._CustomerID = value.CustomerID
                Else
                    Me._CustomerID = CType(Nothing, String)
                End If
                Me.SendPropertyChanged("Customer")
            End If
        End Set
    End Property
 [Association(Name="FK_Orders_Customers", Storage="_Customer", ThisKey="CustomerID", IsForeignKey=true)]
    public Customer Customer
    {
        get
        {
            return this._Customer.Entity;
        }
        set
        {
            Customer previousValue = this._Customer.Entity;
            if (((previousValue != value) 
                        || (this._Customer.HasLoadedOrAssignedValue == false)))
            {
                this.SendPropertyChanging();
                if ((previousValue != null))
                {
                    this._Customer.Entity = null;
                    previousValue.Orders.Remove(this);
                }
                this._Customer.Entity = value;
                if ((value != null))
                {
                    value.Orders.Add(this);
                    this._CustomerID = value.CustomerID;
                }
                else
                {
                    this._CustomerID = default(string);
                }
                this.SendPropertyChanged("Customer");
            }
        }
    }

有关更多信息,请参见基于属性的映射 (LINQ to SQL) 的“关联属性”一节。

LINQ to SQL 方法与数据库存储过程

LINQ to SQL 支持存储过程和用户定义的函数。在 LINQ to SQL 中,您应将数据库定义的这些抽象映射到客户端对象,以便您可以从客户端代码中以强类型化方式访问它们。方法签名与数据库中定义的过程和函数的签名尽可能类似。您可以使用 IntelliSense 来查找这些方法。

通过调用映射的过程返回的结果集为强类型化的集合。

LINQ to SQL 通过使用 FunctionAttributeParameterAttribute 属性将存储过程和函数映射到方法。表示存储过程的方法与表示用户定义的函数的方法通过 IsComposable 属性加以区分。如果此属性设置为 false(默认值),则此方法表示存储过程。如果它设置为 true,则此方法表示数据库函数。

说明:

如果您使用的是 Visual Studio,则可以使用 对象关系设计器 来创建映射到存储过程和用户定义的函数的方法。

示例

   ' This is an example of a stored procedure in the Northwind
   ' sample database. The IsComposable property defaults to false.
   <FunctionAttribute(Name:="dbo.CustOrderHist")> _
Public Function CustOrderHist(<Parameter(Name:="CustomerID", DbType:="NChar(5)")> ByVal customerID As String) As ISingleResult(Of CustOrderHistResult)
       Dim result As IExecuteResult = Me.ExecuteMethodCall(Me, CType(MethodInfo.GetCurrentMethod, MethodInfo), customerID)
       Return CType(result.ReturnValue, ISingleResult(Of CustOrderHistResult))
   End Function
    // This is an example of a stored procedure in the Northwind
    // sample database. The IsComposable property defaults to false.
    [Function(Name="dbo.CustOrderHist")]
    public ISingleResult<CustOrderHistResult> CustOrderHist([Parameter(Name="CustomerID", DbType="NChar(5)")] string customerID)
    {
        IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), customerID);
        return ((ISingleResult<CustOrderHistResult>)(result.ReturnValue));
    }

有关更多信息,请参见 基于属性的映射 (LINQ to SQL)存储过程 (LINQ to SQL) 中的“函数属性”、“存储过程属性”和“参数属性”各节。

请参见

参考

基于属性的映射 (LINQ to SQL)

其他资源

背景信息 (LINQ to SQL)