【问题标题】:Linq To SQL OrderBy, issue when using enumsLinq To SQL OrderBy,使用枚举时的问题
【发布时间】:2008-12-18 15:18:46
【问题描述】:

在对枚举类型进行操作时,我在 LINQ 查询上使用 OrderBy 扩展方法时遇到了一些问题。我使用 Visual Studio 创建了一个常规的 DataContext,只需将所有内容拖放到设计器上即可。然后,我创建了单独的实体模型,它们只是 POCO,我使用存储库模式从我的数据库中获取数据并将它们映射到我自己的实体模型中(或者更确切地说,我有一个存储库模式,它可以构建和 IQueryable这将完成所有这些)。

一切正常,除非我尝试在我已从 short/smallint 映射到枚举的属性上应用 OrderBy(存储库外部)。

以下是相关代码位:

public class Campaign
{
    public long Id { get; set; }
    public string Name { get; set; }
    ....
    public CampaignStatus Status { get; set; }
    ...
}
public enum CampaignStatus : short {
    Active,
    Inactive,
    Todo,
    Hidden
}
public class SqlCampaignRepository : ICampaignRepository
{
...
    public IQueryable<Campaign> Campaigns()
    {
        DataContext db = new DataContext();
        return from c in db.Campaigns
                select new Campaign
                   {
                       Id = c.Id,
                       Name = c.Name,
                       ...
                       Status = (CampaignStatus)c.Status,
                       ...
                   };
     }
}

然后在别处

SqlCampaignRepository rep = new SqlCampaignRepository();
var query = rep.Campaigns().OrderBy(c => c.Status);

这会触发以下异常: System.ArgumentException 未被用户代码处理 Message="参数 'value' 的类型错误。应为 'IQMedia.Models.CampaignType'。实际为 'System.Int16'。" 源="系统.Data.Linq" 堆栈跟踪: ved System.Data.Linq.SqlClient.SqlOrderExpression.set_Expression(SqlExpression 值) 已验证 System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitSelect(SqlSelect 选择) ved System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode 节点) 已验证 System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitIncludeScope(SqlIncludeScope 范围) ...

(对不起里面的丹麦语,ved = by/at)。

我已经尝试在 orderBy 表达式中将 Status 类型转换为 short,但这并没有帮助,如果我也将它转换为实际的 enum 类型也是如此。

非常感谢任何解决此问题的帮助!

【问题讨论】:

    标签: c# linq-to-sql enums


    【解决方案1】:

    你能通过设计器直接在你的DataContext中指定类型CampaignStatus吗?这样值会自动映射到enum

    【讨论】:

      【解决方案2】:

      Campaign 类和Campaigns 有什么关系?如果Campaigns 返回Campaign 对象的集合,请注意您通常不能将select new 映射到实体。

      我想知道如果您在 Select 之前执行 OrderBy 是否会更好?

      最后一个技巧可能是使用简单的 TSQL 创建一个虚假的可组合 [Function]。例如,ABS 可能就足够了。即类似(根据上下文):

          [Function(Name="ABS", IsComposable=true)] 
          public int Abs(int value) 
          { // to prove not used by our C# code... 
              throw new NotImplementedException(); 
          }
      

      那就试试吧:

        .OrderBy(x => ctx.Abs(x.Status))
      

      我还没有测试过上述内容,但可以稍后试一试……不过,它适用于其他一些类似的情况。

      值得一试……

      【讨论】:

        【解决方案3】:

        我的 DataContext 有自己的名为 Campaign 的实体类(当然,它位于不同的命名空间中)。此外,状态列在数据库中保存为 smallint,并且 LINQ Entity 命名空间将其类型列为短 (System.Int16)。

        如果我将 orderby 应用到我的存储库中的查询中,orderby 确实可以工作 - 虽然这是一个更大的事情的一部分,整个想法是不要让存储库应用任何排序、过滤或类似的东西,但是只需将数据库实体类映射到我自己的。这个例子显然有点毫无意义,它几乎是一个直接的映射,但在某些情况下我也添加了本地化。

        另外我忘了添加 - 除非我尝试执行查询(即 - 调用 ToList 或枚举集合),否则显然不会发生异常。

        从更大的角度来看,这个方法被一个服务类使用,然后应该添加过滤、排序和所有这些——所有这些的重点当然是把事情分开一点,但也让如果需要,稍后转换到不同的数据库或不同的 OR/M。

        啊,直到我回复后才看到最后一点 - 我还没有使用 Function 属性的任何经验,但我将无法访问我应该应用排序的类中的数据上下文。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-02
          • 1970-01-01
          • 2012-10-30
          • 1970-01-01
          相关资源
          最近更新 更多