为什么迭代IQueryable会为结果中的每个项目提供第一个值?

时间:2013-04-04 16:33:18

标签: c# .net linq-to-sql

我有一段代码尝试从数据库中查询一些简单的配置参数。但是,使用下面的代码,只要我枚举结果,我就会得到结果中每个项目的第一个值:

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; }
        }
    }
}

这两个关联表非常简单,仅用于规范化目的。它们表示如下:

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; }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

因此,在对我的代码进行更多挖掘和审核之后,我发现了两个问题,经过纠正后会产生预期的结果。

首先,在我的ConfigurationContentsTable实体类中,我的PK字段被配置为查看ConfigurationContextId而不是ConfigurationContentId字段。当我修复这个问题时,当我预期三个时,我开始只得到一个结果。这导致我查看表关联/连接逻辑(参见下面的第二项)。更正了ConfigurationContentsTable中的代码段:

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

其次,对于所有EntityRef&lt;&gt;具有[Association(Storage = ...]属性的属性,我将ThisKeyOtherKey属性颠倒了。一旦我将ConfigurationContentsTable更改为使用ThisKey并使用ConfigurationContextsTable和ConfigurationSectionsTable来使用OtherKey,我就开始看到预期的三个不同结果。

更正了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; }
}