如何使用 ExecuteSqlCommandAsync

How To use ExecuteSqlCommandAsync

我一直在努力弄清楚 ExecuteSqlCommandAsync,但我找不到任何好的文档。

if (OldMarketRightsIDs.Count > 0)
{
    //This is where I want to have the task Begin        
    TaskReturn = Data.MK3Model.Database.ExecuteSqlCommandAsync("DELETE FROM TitleMarketRights WHERE ID in (" + string.Join(", ", OldMarketRightsIDs) + ")");
}

//This is the Code I want To execute in between
var NewMarketRights = MarketRights.Select(m => new
{
    Key = m.Key,
    Value = m.Value.Except(CurrentMarketRights[m.Key].Select(c => c.FK_ProductRight).ToList())
}).ToList();

foreach (var mr in NewMarketRights)
{
    foreach (var ProdID in mr.Value)
    {
        Data.MK3Model.TitleMarketRights.Add(new TitleMarketRight { FK_MarketID = (mr.Key == 0) ? null : (int?)mr.Key, FK_TitleID = ID, FK_ProductRight = ProdID });
    }
}

//This is where I want to wait until the task is complete before continuing
var i = await TaskReturn;

此示例未编译,出现错误 await operator can only be used with an async Method。关于如何让它工作的任何想法

你的代码没问题。它只需要在 async 方法中:

public async Task FooAsync()
{
    if (OldMarketRightsIDs.Count > 0)
    {
        TaskReturn = Data.MK3Model.Database.ExecuteSqlCommandAsync("DELETE FROM TitleMarketRights WHERE ID in (" + string.Join(", ", OldMarketRightsIDs) + ")");
    }

    var NewMarketRights = MarketRights.Select(m => new
    {
        Key = m.Key,
        Value = m.Value.Except(CurrentMarketRights[m.Key].Select(c => c.FK_ProductRight).ToList())
    }).ToList();

    foreach (var mr in NewMarketRights)
    {
        foreach (var ProdID in mr.Value)
        {
            Data.MK3Model.TitleMarketRights.Add(new TitleMarketRight { FK_MarketID = (mr.Key == 0) ? null : (int?)mr.Key, FK_TitleID = ID, FK_ProductRight = ProdID });
        }
    }

    var i = await TaskReturn;
}

这就是允许您使用 await 的原因。在幕后构建了一个状态机来处理您方法的异步性质。该方法需要有 async 关键字和 return 一个 TaskTask<T> 如果你有一个 return 值。

如果您想将其作为 lambda 表达式,则:

Func<Task> fooAsync = async () =>
{
    if (OldMarketRightsIDs.Count > 0)
    {
        TaskReturn = Data.MK3Model.Database.ExecuteSqlCommandAsync("DELETE FROM TitleMarketRights WHERE ID in (" + string.Join(", ", OldMarketRightsIDs) + ")");
    }

    var NewMarketRights = MarketRights.Select(m => new
    {
        Key = m.Key,
        Value = m.Value.Except(CurrentMarketRights[m.Key].Select(c => c.FK_ProductRight).ToList())
    }).ToList();

    foreach (var mr in NewMarketRights)
    {
        foreach (var ProdID in mr.Value)
        {
            Data.MK3Model.TitleMarketRights.Add(new TitleMarketRight { FK_MarketID = (mr.Key == 0) ? null : (int?)mr.Key, FK_TitleID = ID, FK_ProductRight = ProdID });
        }
    }

    var i = await TaskReturn;
};

var task = fooAsync();

你应该这样做:

if (OldMarketRightsIDs.Count > 0)
{        
    await Data.MK3Model.Database.ExecuteSqlCommandAsync("DELETE FROM TitleMarketRights WHERE ID in (" + string.Join(", ", OldMarketRightsIDs) + ")");
}

//This code won't execute till the await has finished
var NewMarketRights = MarketRights.Select(m => new
{
    Key = m.Key,
    Value = m.Value.Except(CurrentMarketRights[m.Key].Select(c => c.FK_ProductRight).ToList())
}).ToList();

foreach (var mr in NewMarketRights)
{
    foreach (var ProdID in mr.Value)
    {
        Data.MK3Model.TitleMarketRights.Add(new TitleMarketRight { FK_MarketID = (mr.Key == 0) ? null : (int?)mr.Key, FK_TitleID = ID, FK_ProductRight = ProdID });
    }
}

当 await 被触发时,状态机将拍摄快照,并且在 Async 函数启动时,进程可以自由地做其他事情。但是在 Async 函数完成触发之前,代码不会在此块中继续。当它发生时,状态机将返回继续触发的点,也就是最后一个 if 大括号。

await 只允许进程在触发此 Async 函数时做其他事情。

还记得让周围的函数包含 async 关键字:

public async void DoSomething()
{

}

所以上面不会 "fire and forget" aka,只是开始并在后台工作。为了实现这一点,我相信你会调用 Data.MK3Model.Database.ExecuteSqlCommandAsync().Start() 来启动它。 MSDN Task