【问题标题】:Perform some operation inside Select statement in LINQ在 LINQ 的 Select 语句中执行一些操作
【发布时间】:2016-02-17 15:09:06
【问题描述】:

我有一个控制器操作方法,它返回 IQueryable<AnswerDTO > ,其中有一个名为“Sequence”的字段。我想在一些计算后设置这个字段。我的做法是

var answer = from dfi in _db.DiaryFormInstances
 //Some Query with LINQ
 select new AnswerDTO()
 {
     Value = dfit.Value,
     //How to perform this operation?
     Sequence = Convert.ToInt32(fti.ItemName.Substring(fti.ItemName.LastIndexOf("_")+1)),
     LastModifiedDate = dfit.LastModifiedDate.Value,
     LastModifiedByID = dfit.LastModifiedByID.Value
 };

如何在select语句中设置这样的Sequence属性?

Sequence = Convert.ToInt32(fti.ItemName.Substring(fti.ItemName.LastIndexOf("_")+1))

如果我在我的操作方法中执行查询,那么我可以轻松地执行此操作。但我想返回 IQueryable,我不想在我的操作方法中执行查询。

我希望 web api 将执行查询,并在执行后正确设置 Sequence 属性。

【问题讨论】:

  • 我看到 dfi 在查询中定义但未在 select 语句中使用,而 dfitfti 已使用但未定义
  • Emdadul,我添加了另一个更强大的答案,我已经在我的机器上的一个小型应用程序中进行了测试。我删除了我之前的答案,因为事实证明 Linq to Entities 中没有所需的功能。

标签: c# .net entity-framework asp.net-web-api asp.net-web-api2


【解决方案1】:

在研究了 Linq to Entities 中可用的功能后,似乎无法使用内置功能以您希望的方式提取数字。

最好的办法是在数据库中创建一个可以调用的自定义函数。为此,首先在您的数据库中创建以下函数(例如,您可以使用 SSMS 直接创建它):

CREATE FUNCTION ExtractSequence
(
    @sequenceString NVARCHAR(50)
)
RETURNS INT
AS
BEGIN
    RETURN CAST(RIGHT(@sequenceString, CHARINDEX('_', REVERSE('_' + @sequenceString)) - 1) AS INT)
END
GO

接下来您需要包含 https://codefirstfunctions.codeplex.com/ 包,它位于 NuGet 上,只需搜索 CodeFirstStoreFunctions

添加上述包后,您需要将modelBuilder.Conventions.Add(new FunctionsConvention("dbo", this.GetType())); 添加到上下文类的OnModelCreating 方法中,例如

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Conventions.Add(new FunctionsConvention("dbo", this.GetType()));
}

接下来,您还需要将以下内容添加到上下文类中:

// First parameter should always be CodeFirstDatabaseSchema, this is just a convention used by the store functions package
// The second parameter should match the name of the function in the DB. You can call the method something else but I'd keep it the same as the function name too
[DbFunction("CodeFirstDatabaseSchema", "ExtractSequence")]
public static int ExtractSequence(string sequenceString)
{
    // No need to provide an implementation as this is like a placeholder for the DB function you created in the DB in the first step
    throw new NotSupportedException();
}

最后,您可以在 Linq to Entity 表达式中使用新函数,因此您可以将选择更改为如下所示:

var answer = from dfi in _db.DiaryFormInstances
select new AnswerDTO()
{
    Value = dfit.Value,
    Sequence = MyDbContext.ExtractSequence(fti.ItemName), // Change MyDbContext to whatever your context class is
    LastModifiedDate = dfit.LastModifiedDate.Value,
    LastModifiedByID = dfit.LastModifiedByID.Value
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-16
    • 1970-01-01
    相关资源
    最近更新 更多