3

Ms Access データベースで Linq データ マッピングを使用しています。いつものように を作成し、OleDbConnectionに渡しDataContextます。

これは、複雑なクエリに基づいてテーブルからデータを取得するために、これまでうまく機能しており、リレーションでさえ、1-N リレーションで子エンティティのリストを自動的に入力するように機能します。

ただし、次のコードを使用してデータを挿入しようとすると:

    [Table(Name = "test_table")]
    public class test_item {
        [Column(IsPrimaryKey = true, IsDbGenerated = true)]
        public int field1;
        [Column]
        public int field2;
    }
    public void Test() {
        Table<test_item> tbl = this.GetTable<test_item>();
        test_item x = new test_item();
        x.field2 = 1222;
        tbl.InsertOnSubmit(x);
        this.SubmitChanges();
    }

次のエラーが表示されます。

"Missing semicolon (;) at end of SQL statement."
at System.Data.OleDb.OleDbCommand.ExecuteCommandTextErrorHandling(OleDbHResult hr)
at System.Data.OleDb.OleDbCommand.ExecuteCommandTextForSingleResult(tagDBPARAMS dbParams, Object& executeResult)
at System.Data.OleDb.OleDbCommand.ExecuteCommandText(Object& executeResult)
at System.Data.OleDb.OleDbCommand.ExecuteCommand(CommandBehavior behavior, Object& executeResult)
at System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method)
at System.Data.OleDb.OleDbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.OleDb.OleDbCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader()
at System.Data.Linq.SqlClient.SqlProvider.Execute(Expression query, QueryInfo queryInfo, IObjectReaderFactory factory, Object[] parentArgs, Object[] userArgs, ICompiledSubQuery[] subQueries, Object lastResult)
at System.Data.Linq.SqlClient.SqlProvider.ExecuteAll(Expression query, QueryInfo[] queryInfos, IObjectReaderFactory factory, Object[] userArguments, ICompiledSubQuery[] subQueries)
at System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query)
at System.Data.Linq.ChangeDirector.StandardChangeDirector.DynamicInsert(TrackedObject item)
at System.Data.Linq.ChangeDirector.StandardChangeDirector.Insert(TrackedObject item)
at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges()
at MyClass.Test() in C:\...\MyClass.cs:line 123

フラグを外せばIsDbGeneratedクラッシュしないのですが、その場合強制的に主キー( x.field1 = 55)を指定する必要があるのですが、自動で割り当ててほしいです。

この例外を回避するにはどうすればよいですか?

4

3 に答える 3

3

私はこれを見ました:)。Linq2SQL の接続タイプの強制の欠如に便乗しているようです;)。Linq2SQL は Access ではサポートされていません。Access SQL と TSQL の類似性により、ほとんどの読み取りクエリと一部の挿入クエリは機能しますが、他のことは単純に実行できず、自動 ID 列を使用した挿入はその 1 つです。その理由は、Linq が同じ挿入コマンドの一部として 2 つのクエリを生成し (1 つはレコードを挿入し、もう 1 つは新しく生成された ID を取得するため)、Access には適していないためです。回避策は可能ですが、かなり醜いです。DataContext をサブクラス化し、問題のあるすべての Insert* メソッド (この場合は InsertTest_Table) を作成し、それらのメソッドを使用して同じトランザクション内で 2 つの連続するコマンドを発行する必要があります。

void InsertTest_Table(Test_Table t)
{
    IDbCommand cmd;
    cmd = Connection.CreateCommand();
    cmd.Transaction = this.Transaction;
    cmd.CommandText = "INSERT INTO [Test_Table] ([Field2]) VALUES (@p0)";
    cmd.Parameters.Add(new OleDbParameter("p0", t.field2));
    cmd.ExecuteNonQuery();

    cmd = Connection.CreateCommand();
    cmd.Transaction = this.Transaction;
    cmd.CommandText = "SELECT @@IDENTITY";
    t.field1 = Convert.ToInt32(cmd.ExecuteScalar());
}

私の提案は、可能であれば Access をダンプし、SQLExpress に切り替えることです (.SDF の方が優れています)。

于 2011-02-06T12:07:21.317 に答える
1

Linq to SQL を使用しているようです。Linq to SQL は、Access ではなく SQL Server 向けに設計されています。

Linq to Entities を試してみませんか?

Access には必要な ADO.NET プロバイダーがあるため、EF で動作するはずであることは理解していますが、実行したことはありません。

于 2011-02-06T18:00:08.133 に答える
0

コードの生成は SQL Server の生成から離れています。SQL Server の場合、MS SQL Server のセミコロンは必要ありません。クラスの部分メソッドを変更してみてください。このリンクを使用してください - http://www.devart.com/linqconnect/docs/ExecuteDynamicMethods.html。多分それはあなたを助けることができます。

于 2011-02-21T16:35:25.703 に答える