8

データベースからいくつかの単純な構成パラメーターを照会しようとするコードのブロックがあります。ただし、以下のコードを使用すると、結果を列挙するとすぐに、結果の各項目の最初の値が取得されます。

var db = new ConfigurationServiceDataContext("Server=vsdcs022.aridev.lcl;Database=ConfigurationService;Trusted_Connection=True;");

var parameters =
    from configContents in db.ConfigurationContents
    where
        configContents.ConfigurationContextsTable.ConfigurationContextName == contextName &&
        configContents.ConfigurationSectionTable.ConfigurationSectionName == sectionName
    select configContents;

// print stuff for debugging purposes:
foreach (var parameter in parameters)
{
    Console.WriteLine("key = '{0}', value = '{1}'", parameter.ConfigurationKey, parameter.ConfigurationValue);
}

return parameters.ToDictionary(parameter => parameter.ConfigurationKey, parameter => parameter.ConfigurationValue);

結果を (新しい辞書に追加する前に) 印刷すると、次のような結果が得られます。

key = 'key1', value = 'value1'
key = 'key1', value = 'value1'
key = 'key1', value = 'value1'

しかし、選択行を匿名型に置き換えると、問題なく動作します。

    select new { configContents.ConfigurationKey, configContents.ConfigurationValue };

この匿名型を使用すると、次の結果が得られます。

key = 'key1', value = 'value1'
key = 'key2', value = 'value2'
key = 'key3', value = 'value3'

私はこれを数時間調査しましたが、役に立ちませんでした。匿名型で良いと言えますが、これは本当に気になります。コードの最初のブロックが問題なく動作することを示唆する例をたくさん見てきました。私はばかげたことをしていると確信しています、私はそれを見ることができません!

何か案は?

以下は、DataContext 実装から始めて使用しているモデルの完全な詳細です。

using System.Data.Linq;
using Ari.Core.ConfigurationService.LinqEntityClasses;

namespace Ari.Core.ConfigurationService
{
    class ConfigurationServiceDataContext : DataContext
    {
        public Table<ConfigurationContentsTable> ConfigurationContents;
        public Table<ConfigurationContextsTable> ConfigurationContexts;
        public Table<ConfigurationSectionsTable> ConfigurationSections;

        public ConfigurationServiceDataContext(string connectionString) : base(connectionString) {}
    }
}

コア コンテンツ テーブルは、私の ConfigurationContentsTable エンティティ クラスによって表されます。

using System.Data.Linq;
using System.Data.Linq.Mapping;

namespace Ari.Core.ConfigurationService.LinqEntityClasses
{
    [Table(Name = "ConfigurationContents")]
    class ConfigurationContentsTable
    {
        private long _configurationContextId;
        private string _configurationKey;
        private string _configurationValue;
        private EntityRef<ConfigurationContextsTable> _configurationContextsTable;
        private EntityRef<ConfigurationSectionsTable> _configurationSectionsTable;

        public ConfigurationContentsTable()
        {
            _configurationContextsTable = new EntityRef<ConfigurationContextsTable>();
            _configurationSectionsTable = new EntityRef<ConfigurationSectionsTable>();
        }

        [Column(Storage = "_configurationContextId", DbType = "BigInt NOT NULL IDENTITY", IsPrimaryKey = true,
            IsDbGenerated = true)]
        public long ConfigurationContextId
        {
            get { return _configurationContextId; }
        }

        [Column(Storage = "_configurationKey")]
        public string ConfigurationKey
        {
            get { return _configurationKey; }
            set { _configurationKey = value; }
        }

        [Column(Storage = "_configurationValue")]
        public string ConfigurationValue
        {
            get { return _configurationValue; }
            set { _configurationValue = value; }
        }

        [Association(Storage = "_configurationContextsTable", OtherKey = "ConfigurationContextId")]
        public ConfigurationContextsTable ConfigurationContextsTable
        {
            get { return _configurationContextsTable.Entity; }
            set { _configurationContextsTable.Entity = value; }
        }

        [Association(Storage = "_configurationSectionsTable", OtherKey = "ConfigurationSectionId")]
        public ConfigurationSectionsTable ConfigurationSectionTable
        {
            get { return _configurationSectionsTable.Entity; }
            set { _configurationSectionsTable.Entity = value; }
        }
    }
}

関連する 2 つのテーブルは非常に単純で、正規化の目的でのみ存在します。それらは次のように表されます。

using System.Data.Linq;
using System.Data.Linq.Mapping;

namespace Ari.Core.ConfigurationService.LinqEntityClasses
{
    [Table(Name = "ConfigurationContexts")]
    class ConfigurationContextsTable
    {
        private long _configurationContextId;
        private string _configurationContextName;
        private EntityRef<ConfigurationContentsTable> _configurationContentsTable;

        public ConfigurationContextsTable()
        {
            _configurationContentsTable = new EntityRef<ConfigurationContentsTable>();
        }

        [Column(Storage = "_configurationContextId", DbType = "BigInt NOT NULL IDENTITY", IsPrimaryKey = true,
            IsDbGenerated = true)]
        public long ConfigurationContextId
        {
            get { return _configurationContextId; }
        }

        [Column(Storage = "_configurationContextName")]
        public string ConfigurationContextName
        {
            get { return _configurationContextName; }
            set { _configurationContextName = value; }
        }

        [Association(Storage = "_configurationContentsTable", ThisKey = "ConfigurationContextId")]
        public ConfigurationContentsTable ConfigurationContentsTable
        {
            get { return _configurationContentsTable.Entity; }
            set { _configurationContentsTable.Entity = value; }
        }
    }
}

そして最後に:

using System.Data.Linq;
using System.Data.Linq.Mapping;

namespace Ari.Core.ConfigurationService.LinqEntityClasses
{
    [Table(Name = "ConfigurationSections")]
    class ConfigurationSectionsTable
    {
        private long _configurationSectionId;
        private string _configurationSectionName;
        private EntityRef<ConfigurationContentsTable> _configurationContentsTable;

        public ConfigurationSectionsTable()
        {
            _configurationContentsTable = new EntityRef<ConfigurationContentsTable>();
        }

        [Column(Storage = "_configurationSectionId", DbType = "BigInt NOT NULL IDENTITY", IsPrimaryKey = true,
            IsDbGenerated = true)]
        public long ConfigurationSectionId
        {
            get { return _configurationSectionId; }
        }

        [Column(Storage = "_configurationSectionName")]
        public string ConfigurationSectionName
        {
            get { return _configurationSectionName; }
            set { _configurationSectionName = value; }
        }

        [Association(Storage = "_configurationContentsTable", ThisKey = "ConfigurationSectionId")]
        public ConfigurationContentsTable ConfigurationContentsTable
        {
            get { return _configurationContentsTable.Entity; }
            set { _configurationContentsTable.Entity = value; }
        }
    }
}
4

1 に答える 1

0

そのため、コードをさらに掘り下げて確認した結果、2 つの問題が見つかりました。これらの問題を修正すると、期待どおりの結果が得られます。

まず、ConfigurationContentsTable エンティティ クラスで、フィールドではConfigurationContextIdなくを参照するように PK フィールドを構成しましたConfigurationContentId。これを修正したところ、3 つ期待していた結果が 1 つしか得られなくなりました。これにより、テーブルの関連付け/結合ロジックに注目しました (以下の 2 番目の項目を参照)。ConfigurationContentsTable の修正されたコード スニペット:

[Column(Storage = "_configurationContentId", DbType = "BigInt NOT NULL IDENTITY", IsPrimaryKey = true, IsDbGenerated = true)]
public long ConfigurationContentId
{
    get { return _configurationContentId; }
}

[Association(Storage = ...]次に、属性を持つすべての EntityRef<> プロパティについて、ThisKeyOtherKeyプロパティを逆にしました。ConfigurationContentsTable を使用するように変更し、ThisKeyConfigurationContextsTable と ConfigurationSectionsTable を使用するように変更するとOtherKey、予想される 3 つの異なる結果が表示されるようになりました。

ConfigurationContentsTable の修正されたコード:

[Association(Storage = "_configurationContextsTable", ThisKey = "ConfigurationContextId")]
public ConfigurationContextsTable ConfigurationContextsTable
{
    get { return _configurationContextsTable.Entity; }
    set { _configurationContextsTable.Entity = value; }
}

[Association(Storage = "_configurationSectionsTable", ThisKey = "ConfigurationSectionId")]
public ConfigurationSectionsTable ConfigurationSectionsTable
{
    get { return _configurationSectionsTable.Entity; }
    set { _configurationSectionsTable.Entity = value; }
}

ConfigurationContextsTable の修正されたコード:

[Association(Storage = "_configurationContentsTable", OtherKey = "ConfigurationContextId")]
public ConfigurationContentsTable ConfigurationContentsTable
{
    get { return _configurationContentsTable.Entity; }
    set { _configurationContentsTable.Entity = value; }
}

最後に、ConfigurationSectionsTable のコードを修正しました。

[Association(Storage = "_configurationContentsTable", OtherKey = "ConfigurationSectionId")]
public ConfigurationContentsTable ConfigurationContentsTable
{
    get { return _configurationContentsTable.Entity; }
    set { _configurationContentsTable.Entity = value; }
}
于 2013-04-04T20:07:01.053 に答える