65.9K
CodeProject 正在变化。 阅读更多。
Home

为 LINQ 绑定的数据设置默认值

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.53/5 (8投票s)

2008年2月21日

CPOL

4分钟阅读

viewsIcon

102006

downloadIcon

134

如何阻止 LINQ 尝试将 null 数据插入您的数据库。

Article_src

引言

对 Microsoft 新的 LINQ 技术所展现出的 ORM 行为印象深刻,我决定在下一个项目中使用它之前进行一个开发实验。尽管 LINQ 绝对是未来的方向,但似乎存在一些不足之处,需要一些变通。在这里,我将写下一种相当棘手的行为,其中 LINQ 对象的属性被设置为 null 值,导致数据库拒绝更新和插入不允许 null 数据的列。

Using the Code

在使用 ASP.NET DetailsView 控件和底层的 LINQ DataSource 时,我遇到了一个问题。问题是:当我使用 LINQ 加载对象时,而不是使用从数据库派生的属性的默认值,每个属性的默认值都是 null。作为一个好的 DBA,我从不(没有充分理由)在数据库中留下 null,所以我的表总是为每个列分配默认值。然而,当 LINQ 对象被发送回数据库时,操作会失败,因为数据库拒绝了 LINQ 层试图插入的 null 数据。

我认为这是设计上的一个缺陷。默认情况下,LINQ 对象应该使用映射回底层数据存储中使用的默认值的属性进行初始化。

无论如何,最好通过一个简单的例子来演示这个问题,然后展示一种变通方法……
我有一个简单的数据表……



CREATE TABLE [dbo].[Table1](
    [Col1] [int] IDENTITY(1,1) NOT NULL,
    [Col2] [nvarchar](50) NOT NULL CONSTRAINT [DF_Table1_Col2]  DEFAULT (''),
    [Col3] [int] NOT NULL CONSTRAINT [DF_Table1_col3]  DEFAULT ((0)),
    [Col4] [datetime] NOT NULL CONSTRAINT [DF_Table1_col4]  DEFAULT (getdate()),
 CONSTRAINT [PK_Table1] PRIMARY KEY CLUSTERED
(
    [Col1] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = _
    OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

……以及一个位于该表之上的 LINQ 类

接下来,我在项目的默认页面 (default.aspx) 中添加一个 LinqDataSource,并设置一个基于底层数据主键的过滤参数,并告知 datasource 我也希望能够编辑数据。

<asp:LinqDataSource ID="LinqDataSource1" runat="server"
            ContextTypeName="DataClassesDataContext" EnableUpdate="True"
            TableName="Table1s" Where="Col1 == @Col1">
<WhereParameters>
          <asp:QueryStringParameter Name="Col1" QueryStringField="Col1" Type="Int32" />
      </WhereParameters>
</asp:LinqDataSource>

作为数据的一个 UI,我将一个 DetailsView 控件拖到页面上,并将其绑定到 LinqDataSource

<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
        DataKeyNames="Col1" DataSourceID="LinqDataSource1" Height="50px" Width="125px">
        <Fields>
            <asp:BoundField DataField="Col1" HeaderText="Col1" InsertVisible="False"
                ReadOnly="True" SortExpression="Col1" />
            <asp:BoundField DataField="Col2" HeaderText="Col2" SortExpression="Col2" />
            <asp:BoundField DataField="Col3" HeaderText="Col3" SortExpression="Col3" />
            <asp:BoundField DataField="Col4" HeaderText="Col4" SortExpression="Col4" />
            <asp:CommandField ShowEditButton="True" />
        </Fields>
    </asp:DetailsView>

我手动向我的数据表中添加一条记录,以便有一些数据可以编辑

请注意,Col2 是空的,但根据定义,它应该是一个空的 string

[Col2] [nvarchar](50) NOT NULL CONSTRAINT [DF_Table1_Col2]  DEFAULT (''),

让我们尝试编辑这一行的数据(确保提供查询 string 参数 Col1=1

所以,我将 Col2 留空,然后点击更新链接。

Cannot insert the value NULL into column 'Col2', table 'TestDB.dbo.Table1'; 
    column does not allow nulls. UPDATE fails.
The statement has been terminated.
Description: An unhandled exception occurred during the execution of the 
    current web request. Please review the stack trace for more information about 
    the error and where it originated in the code.

Exception Details: System.Data.SqlClient.SqlException: 
    Cannot insert the value NULL into column 'Col2', table 'TestDB.dbo.Table1'; 
    column does not allow nulls. UPDATE fails.
The statement has been terminated.

Source Error:
An unhandled exception was generated during the execution of the current web request. 
    Information regarding the origin and location of the exception can be identified 
    using the exception stack trace below.

Stack Trace:

[SqlException (0x80131904): Cannot insert the value NULL into column 'Col2', 
    table 'TestDB.dbo.Table1'; column does not allow nulls. UPDATE fails.
The statement has been terminated.]
   System.Data.SqlClient.SqlConnection.OnError_
        (SqlException exception, Boolean breakConnection) +925466
   System.Data.SqlClient.SqlInternalConnection.OnError_
        (SqlException exception, Boolean breakConnection) +800118
   System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning_
        (TdsParserStateObject stateObj) +186
   System.Data.SqlClient.TdsParser.Run_
        (RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, _
        BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +1932
   System.Data.SqlClient.SqlCommand.FinishExecuteReader_
        (SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +149
   System.Data.SqlClient.SqlCommand.RunExecuteReaderTds_
        (CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, _
        Boolean async) +1005
   System.Data.SqlClient.SqlCommand.RunExecuteReader_
        (CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, _
        String method, DbAsyncResult result) +132
   System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery_
        (DbAsyncResult result, String methodName, Boolean sendToPipe) +149
   System.Data.SqlClient.SqlCommand.ExecuteNonQuery() +135
   System.Data.Linq.SqlClient.SqlProvider.Execute_
        (Expression query, QueryInfo queryInfo, IObjectReaderFactory factory, _
        Object[] parentArgs, Object[] userArgs, ICompiledSubQuery[] subQueries, _
        Object lastResult) +229
   System.Data.Linq.SqlClient.SqlProvider.ExecuteAll_
        (Expression query, QueryInfo[] queryInfos, IObjectReaderFactory factory, _
        Object[] userArguments, ICompiledSubQuery[] subQueries) +129
   System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute_
        (Expression query) +878
   System.Data.Linq.StandardChangeDirector.DynamicUpdate(TrackedObject item) +127
   System.Data.Linq.StandardChangeDirector.Update(TrackedObject item) +168
   System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode) +433
   System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode) +1155
   System.Data.Linq.DataContext.SubmitChanges() +82
   System.Web.UI.WebControls.LinqToSqlWrapper.SubmitChanges(DataContext dataContext) +9
   System.Web.UI.WebControls.LinqDataSourceView.UpdateDataObject_
    (Object dataContext, Object table, Object oldDataObject, Object newDataObject) +106
   System.Web.UI.WebControls.LinqDataSourceView.ExecuteUpdate_
    (IDictionary keys, IDictionary values, IDictionary oldValues) +326
   System.Web.UI.DataSourceView.Update_
        (IDictionary keys, IDictionary values, IDictionary oldValues, _
        DataSourceViewOperationCallback callback) +78
   System.Web.UI.WebControls.DetailsView.HandleUpdate_
        (String commandArg, Boolean causesValidation) +1152
   System.Web.UI.WebControls.DetailsView.HandleEvent_
        (EventArgs e, Boolean causesValidation, String validationGroup) +440
   System.Web.UI.WebControls.DetailsView.OnBubbleEvent(Object source, EventArgs e) +95
   System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +35
   System.Web.UI.WebControls.DetailsViewRow.OnBubbleEvent_
        (Object source, EventArgs e) +109
   System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +35
   System.Web.UI.WebControls.LinkButton.OnCommand(CommandEventArgs e) +115
   System.Web.UI.WebControls.LinkButton.RaisePostBackEvent(String eventArgument) +132
   System.Web.UI.WebControls.LinkButton.System.Web.UI.IPostBackEventHandler._
        RaisePostBackEvent(String eventArgument) +7
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, _
        String eventArgument) +11
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +177
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, _
        Boolean includeStagesAfterAsyncPoint) +1746

________________________________________
Version Information: Microsoft .NET Framework Version:2.0.50727.1433; 
    ASP.NET Version:2.0.50727.1433

很烦人,对吧?
首先,这不是一个新插入,所以当 LINQ 对象加载该行的数据时,Col2 应该被设置为从数据库中的 col2 获取的值,这是一个空的 string。其次,如果是一个新插入,那么我希望使用表中定义中为每个列设置的默认值,而不是 null

所以,让我们尝试一个新的插入。我修改了 DataSourceDetailsView 以支持插入和更新

<asp:LinqDataSource ID="LinqDataSource1" runat="server"
            ContextTypeName="DataClassesDataContext" EnableInsert="True"
            EnableUpdate="True" TableName="Table1s" Where="Col1 == @Col1">
            <WhereParameters>
                <asp:QueryStringParameter Name="Col1" QueryStringField="Col1" 
                Type="Int32" />
            </WhereParameters>
        </asp:LinqDataSource>

   <asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
            DataKeyNames="Col1" DataSourceID="LinqDataSource1" 
                Height="50px" Width="125px">
            <Fields>
                <asp:BoundField DataField="Col1" HeaderText="Col1" InsertVisible="False"
                    ReadOnly="True" SortExpression="Col1" />
                <asp:BoundField DataField="Col2" HeaderText="Col2" 
                        SortExpression="Col2" />
                <asp:BoundField DataField="Col3" HeaderText="Col3" 
                        SortExpression="Col3" />
                <asp:BoundField DataField="Col4" HeaderText="Col4" 
                        SortExpression="Col4" />
                <asp:CommandField ShowEditButton="True" ShowInsertButton="True" />
            </Fields>
        </asp:DetailsView>

现在我尝试一个全新的插入,将 DetailsView 上的每个列都留空

然后点击插入链接

SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.
Description: An unhandled exception occurred during the execution of 
    the current web request. Please review the stack trace for more information 
    about the error and where it originated in the code.

Exception Details: System.Data.SqlTypes.SqlTypeException: SqlDateTime overflow. 
    Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.

Source Error:
An unhandled exception was generated during the execution of the current web request. 
    Information regarding the origin and location of the exception can be identified 
    using the exception stack trace below.

Stack Trace:

[SqlTypeException: SqlDateTime overflow. 
    Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.]
   System.Data.SqlTypes.SqlDateTime.FromTimeSpan(TimeSpan value) +653497
   System.Data.SqlTypes.SqlDateTime.FromDateTime(DateTime value) +150
   System.Data.SqlTypes.SqlDateTime..ctor(DateTime value) +13
   System.Data.SqlClient.MetaType.FromDateTime(DateTime dateTime, Byte cb) +56
   System.Data.SqlClient.TdsParser.WriteValue_
        (Object value, MetaType type, Byte scale, Int32 actualLength, _
        Int32 encodingByteSize, Int32 offset, _
        TdsParserStateObject stateObj) +519
   System.Data.SqlClient.TdsParser.TdsExecuteRPC_
        (_SqlRPC[] rpcArray, Int32 timeout, Boolean inSchema, _
        SqlNotificationRequest notificationRequest, TdsParserStateObject stateObj, _
        Boolean isCommandProc) +4163
   System.Data.SqlClient.SqlCommand.RunExecuteReaderTds_
        (CommandBehavior cmdBehavior, RunBehavior runBehavior, _
        Boolean returnStream, Boolean async) +1005
   System.Data.SqlClient.SqlCommand.RunExecuteReader_
        (CommandBehavior cmdBehavior, RunBehavior runBehavior, _
        Boolean returnStream, String method, DbAsyncResult result) +132
   System.Data.SqlClient.SqlCommand.RunExecuteReader_
        (CommandBehavior cmdBehavior, RunBehavior runBehavior, _
        Boolean returnStream, String method) +32
   System.Data.SqlClient.SqlCommand.ExecuteReader_
        (CommandBehavior behavior, String method) +122
   System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) +12
   System.Data.Common.DbCommand.ExecuteReader() +9
   System.Data.Linq.SqlClient.SqlProvider.Execute_
        (Expression query, QueryInfo queryInfo, IObjectReaderFactory factory, _
        Object[] parentArgs, Object[] userArgs, ICompiledSubQuery[] subQueries, _
        Object lastResult) +903
   System.Data.Linq.SqlClient.SqlProvider.ExecuteAll_
        (Expression query, QueryInfo[] queryInfos, IObjectReaderFactory factory, _
        Object[] userArguments, ICompiledSubQuery[] subQueries) +129
   System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute_
        (Expression query) +878
   System.Data.Linq.StandardChangeDirector.DynamicInsert(TrackedObject item) +261
   System.Data.Linq.StandardChangeDirector.Insert(TrackedObject item) +168
   System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode) +250
   System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode) +1155
   System.Data.Linq.DataContext.SubmitChanges() +82
   System.Web.UI.WebControls.LinqToSqlWrapper.SubmitChanges(DataContext dataContext) +9
   System.Web.UI.WebControls.LinqDataSourceView.InsertDataObject_
        (Object dataContext, Object table, Object newDataObject) +82
   System.Web.UI.WebControls.LinqDataSourceView.ExecuteInsert(IDictionary values) +267
   System.Web.UI.DataSourceView.Insert_
        (IDictionary values, DataSourceViewOperationCallback callback) +72
   System.Web.UI.WebControls.DetailsView.HandleInsert_
        (String commandArg, Boolean causesValidation) +390
   System.Web.UI.WebControls.DetailsView.HandleEvent_
        (EventArgs e, Boolean causesValidation, String validationGroup) +602
   System.Web.UI.WebControls.DetailsView.OnBubbleEvent(Object source, EventArgs e) +95
   System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +35
   System.Web.UI.WebControls.DetailsViewRow.OnBubbleEvent_
        (Object source, EventArgs e) +109
   System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +35
   System.Web.UI.WebControls.LinkButton.OnCommand(CommandEventArgs e) +115
   System.Web.UI.WebControls.LinkButton.RaisePostBackEvent(String eventArgument) +132
   System.Web.UI.WebControls.LinkButton.System.Web.UI.IPostBackEventHandler._
        RaisePostBackEvent(String eventArgument) +7
   System.Web.UI.Page.RaisePostBackEvent_
        (IPostBackEventHandler sourceControl, String eventArgument) +11
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +177
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, _
        Boolean includeStagesAfterAsyncPoint) +1746

________________________________________
Version Information: Microsoft .NET Framework Version:2.0.50727.1433; 
    ASP.NET Version:2.0.50727.1433

嗯,我以为我在表定义中将该默认值设置为了 GetDate()

所以我在想,一定有什么方法可以告诉我的 LINQ 层让数据库处理默认值,停止搞砸事情。

如果我查看 LINQ 设计器代码隐藏文件,我可以看到在每个与底层数据库相关的属性索引器上方设置了 LINQ 属性,这里以 Col2 为例

[Column(Storage="_Col2", DbType="NVarChar(50) NOT NULL", CanBeNull=false)]
    public string Col2
    {
        get
        {
            return this._Col2;
        }
        set
        {
            if ((this._Col2 != value))
            {
                this.OnCol2Changing(value);
                this.SendPropertyChanging();
                this._Col2 = value;
                this.SendPropertyChanged("Col2");
                this.OnCol2Changed();
            }
        }
    }

所以它知道它不能是 null,但其属性的默认值却是 null。抱歉,这很不聪明。我查看了其他可以设置的标志,也许可以强制 LINQ 使用数据库默认值。智能感知给了我以下选项:

IsDbGenerated 看起来是一个相当不错的猜测,所以我尝试了一下

[Column(Storage="_Col2", DbType="NVarChar(50) NOT NULL", _
    CanBeNull=false, IsDbGenerated=true)]

我再次尝试编辑我的数据,但在更新时出现以下错误

Value of member 'Col2' of an object of type 'Table1' changed.
A member that is computed or generated by the database cannot be changed.
Description: An unhandled exception occurred during the execution of the 
    current web request. Please review the stack trace for more information 
    about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: 
    Value of member 'Col2' of an object of type 'Table1' changed.
A member that is computed or generated by the database cannot be changed.

Source Error:
An unhandled exception was generated during the execution of the current web request. 
    Information regarding the origin and location of the exception can be identified 
    using the exception stack trace below.

Stack Trace:

[InvalidOperationException: Value of member 'Col2' of an object of type 'Table1' changed.
A member that is computed or generated by the database cannot be changed.]
   System.Data.Linq.ChangeProcessor.CheckForInvalidChanges(TrackedObject tracked) +291
   System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode) +415
   System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode) +1155
   System.Data.Linq.DataContext.SubmitChanges() +82
   System.Web.UI.WebControls.LinqToSqlWrapper.SubmitChanges(DataContext dataContext) +9
   System.Web.UI.WebControls.LinqDataSourceView.UpdateDataObject_
        (Object dataContext, Object table, Object oldDataObject, _
        Object newDataObject) +106
   System.Web.UI.WebControls.LinqDataSourceView.ExecuteUpdate_
        (IDictionary keys, IDictionary values, IDictionary oldValues) +326
   System.Web.UI.DataSourceView.Update(IDictionary keys, IDictionary values, _
        IDictionary oldValues, DataSourceViewOperationCallback callback) +78
   System.Web.UI.WebControls.DetailsView.HandleUpdate_
        (String commandArg, Boolean causesValidation) +1152
   System.Web.UI.WebControls.DetailsView.HandleEvent_
        (EventArgs e, Boolean causesValidation, String validationGroup) +440
   System.Web.UI.WebControls.DetailsView.OnBubbleEvent(Object source, EventArgs e) +95
   System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +35
   System.Web.UI.WebControls.DetailsViewRow.OnBubbleEvent_
        (Object source, EventArgs e) +109
   System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +35
   System.Web.UI.WebControls.LinkButton.OnCommand(CommandEventArgs e) +115
   System.Web.UI.WebControls.LinkButton.RaisePostBackEvent(String eventArgument) +132
   System.Web.UI.WebControls.LinkButton.System.Web.UI.IPostBackEventHandler._
        RaisePostBackEvent(String eventArgument) +7
   System.Web.UI.Page.RaisePostBackEvent_
        (IPostBackEventHandler sourceControl, String eventArgument) +11
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +177
   System.Web.UI.Page.ProcessRequestMain_
        (Boolean includeStagesBeforeAsyncPoint, _
        Boolean includeStagesAfterAsyncPoint) +1746

________________________________________
Version Information: Microsoft .NET Framework Version:2.0.50727.1433; 
    ASP.NET Version:2.0.50727.1433

现在,我真的开始感到沮丧了。我花了几个小时在这上面,并且在网上搜索解决方案,希望能找到一个不需要我编写代码的办法。到目前为止还没有成功。

所以,这是我的变通方法

我绝对不想编写任何显式绑定到任何表定义的代码,因为如果表发生更改,它肯定会成为维护问题。我也不想编写部分方法来检查 LINQ 属性在设置时的 null 值,因为这意味着更多的维护代码。所以,我认为最好的办法是挂钩 DetailsView 控件的更新事件,并确保在尝试将 LINQ 对象渗透回数据库之前正确初始化它。我修改了 LinqDataSource 控件,以便在 OnUpdating OnInserting 方法触发时调用一个检查方法,如下所示:

  <asp:LinqDataSource ID="LinqDataSource1" runat="server"
            ContextTypeName="DataClassesDataContext" EnableInsert="True"
            EnableUpdate="True" TableName="Table1s" Where="Col1 == _
                @Col1" OnUpdating="SetDefaultUpdateValues" _
                OnInserting="SetDefaultInsertValues">
            <WhereParameters>
                <asp:QueryStringParameter Name="Col1" QueryStringField="Col1" _
                        Type="Int32" />
            </WhereParameters>
        </asp:LinqDataSource>

后台代码如下:

using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Reflection;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    private void SetDefaults(object LinqObj)
    {
        // get the properties of the LINQ Object
        PropertyInfo[] props = LinqObj.GetType().GetProperties();

        // iterate through each property of the class
        foreach (PropertyInfo prop in props)
        {
            // attempt to discover any metadata relating to underlying data columns
            try
            {
                // get any column attributes created by the Linq designer
                object[] customAttributes = prop.GetCustomAttributes
                (typeof(System.Data.Linq.Mapping.ColumnAttribute), false);

                // if the property has an attribute letting us know that 
                // the underlying column data cannot be null
                if (((System.Data.Linq.Mapping.ColumnAttribute)
                (customAttributes[0])).DbType.ToLower().IndexOf("not null") != -1)
                {
                    // if the current property is null or Linq has set a date time 
                // to its default '01/01/0001 00:00:00'
                    if (prop.GetValue(LinqObj, null) == null || prop.GetValue(LinqObj, 
                    null).ToString() == (new DateTime(1, 1, 1, 0, 0, 0)).ToString())
                    {

                        // set the default values here : could re-query the database, 
                        // but would be expensive so just use defaults coded here
                        switch (prop.PropertyType.ToString())
                        {
                            // System.String / NVarchar
                            case "System.String":
                                prop.SetValue(LinqObj, String.Empty, null);
                                break;
                            case "System.Int32":
                            case "System.Int64":
                            case "System.Int16":
                                prop.SetValue(LinqObj, 0, null);
                                break;
                            case "System.DateTime":
                                prop.SetValue(LinqObj, DateTime.Now, null);
                                break;
                        }
                    }
                }
            }
            catch
            {
                // could do something here ...
            }
        }
    }

    // set LINQ objects default values for new insert
    protected void SetDefaultInsertValues(object sender, LinqDataSourceInsertEventArgs e)
    {
        SetDefaults(e.NewObject);
    }

    // set LINQ objects default values for update
    protected void SetDefaultUpdateValues(object sender, LinqDataSourceUpdateEventArgs e)
    {
        SetDefaults(e.NewObject);
    }
}

关注点

上述方法的不足之处在于,代码中设置的默认值不是从数据库派生的。这可以纠正,但成本很高。遗憾的是,LINQ 设计器在创建类时没有将默认列值作为元数据添加。我猜想 Microsoft 很快会找到一个解决方案。

© . All rights reserved.