String.Format in linq query



我被困在一个奇怪的问题上。我有一个看起来像这样的CashGameGeneralViewModel

public class CashGameGeneralViewModel
{
    public string Limit { get; set; }
    public int HandsPlayed { get; set; }
    public float AmountWon { get; set; }
}

以下是应该返回某个玩家玩的所有手牌的方法:

public List<CashGameGeneralViewModel> GetAllHands(string playerToFind)
    {
        HoldemHandContext db = new HoldemHandContext();
        int playerId = GetPlayerId(playerToFind);
        var holdemHandResult = (from phh in db.PlayersInHoldemHands
                                from hh in db.HoldemHands
                                where hh.Id == phh.HandPlayed && phh.PlayerId == playerId
                                select new CashGameGeneralViewModel()
                                           {
                                               Limit = //"some text",
                                               String.Format("{0:0.00}", hh.SBlindAmount) + "/" +
                                               String.Format("{0:0.00}", hh.BBlindAmount),
                                               HandsPlayed = db.HoldemHands.Distinct().Count(),
                                               AmountWon = 0
                                           }
                                ).ToList();
        return holdemHandResult;
    }
    public int GetPlayerId(string playerToFind)
    {
        HoldemHandContext db = new HoldemHandContext();
        int playerId = (from p in db.Players
                        where p.ScreenName == playerToFind
                        select p.Id).FirstOrDefault();
        return playerId;
    }

现在的问题是

Limit = //"some text",
String.Format("{0:0.00}", hh.SBlindAmount) + "/" +
String.Format("{0:0.00}", hh.BBlindAmount)

.part。 hh.SBlindAmounthh.BBlindAmount是浮点值。我想使用String.Format因为0.10被缩短为0.1并且使用字符串格式,我得到了我想要的。但是我得到了一个例外,上面写着:

"在类型'PokerRecord.View.CashGameGeneralUC'上调用与指定的绑定约束匹配的构造函数引发了异常。行号"60"和行位置"18"。

当我删除 string.format 并放入一些"常规"字符串时,一切正常......有人知道为什么吗?

我认为对于您要做的事情(将特定的浮点数格式化为字符串),您希望重载.ToString()允许您提供格式提供程序。

SmallBlind.ToString("{0:0.00}")

您可能正在寻找的内容可能最好地代表:

Limit = string.Format("{0} / {1}",
           SmallBlind.ToString("{0:0.00}"),
           BigBlind.ToString("{0:0.00}")),
//Rest of statement here...

根据您收到的错误(我昨天在问题中遇到了类似的错误),这是我的解决方案:

Limit = GetLimit(SmallBlind, BigBlind),
//Rest of Statement Here

然后使用字符串定义获取限制。格式:

private string GetLimit(double smallBlind, double bigBlind)
{
    return string.Format("{0} / {1}",
           smallBlind.ToString("{0:0.00}"),
           bigBlind.ToString("{0:0.00}"));
}

我会把它留给比我更好的专家来解释为什么这会导致 Linq 失败,但这应该可以让你绕过它。

当然,这假设您的CashGameGeneralViewModel由于某种原因不应该知道盲注。 如果可以,解决方案(已经在另一个答案中提到)是让 Limit getter 返回预先格式化的字符串。

可能有更好的方法来做我正在做的事情,但是,遇到你遇到的同样问题,这就是我解决它的方式。

我刚刚想到的另一个答案,以及我可能更喜欢这样做的方式。我会说只需将这些原始值存储在 ViewModel 中,然后更改 Limit 属性以仅基于这些值创建字符串:

public string Limit { get { return string.Format("{0:0.00}/{1:0.00}", SmallBlind, BigBlind); } }

编辑:

我将添加我更喜欢这种方式的理由 - 它是非破坏性的。但是,如果您的 ViewModel 不会发生太大变化,或者您知道将来永远不需要 BigBlind/SmallBlind 属性,那么这可能是矫枉过正或完全不必要的。

问题是您尝试执行的操作目前与SQL不兼容。您可能需要先获取临时对象中的数据,然后执行到所需对象的简单转换。或者,您可能希望该对象的原始值和另一个属性仅用于显示目的,这将以您喜欢的任何格式返回原始值。

长答案:

有些东西不能很好地从 CLR 方法转换为 TSQL。日期格式设置就是一个很好的示例,因为 .ToString(string s), .短...etc 方法依赖于大量特定于区域设置的设置来格式化最终结果。(分隔符,不同日期部分的顺序,使用的日历时代,月/日名称等)。T-SQL没有像.net那样详细支持所有这些特定于区域设置的格式设置,其他RDBMSes SQL方言也没有。换句话说,将 .net 方法 DateTime.ToShortDateString 转换为 TSQL 将导致非常大的 SQL 块考虑所有特定于区域设置的格式因素,或者会导致方法返回与 .net 等效项不同的结果。(这会更加令人困惑)。

为了说明 .net 的日期和时间格式设置中涉及大量特定于区域设置的逻辑,我在今天日期的几个不同区域性/区域设置下包含了 DateTime.ToShortDateString 和 DateTime.ToLongDateString 的输出:

en-us (US English):
11/15/2010
Monday, November 15, 2010
sv-se (Swedish):
2010-11-15
den 15 november 2010
zh-cn (Chinese):
2010/11/15
2010年11月15日
ar-sa (Arabic / Saudi Arabia):
09/12/31
09/ذو الحجة/1431
th-th (Thai):
15/11/2553
15 พฤศจิกายน 2553

是的,没错,上面的所有五个示例都是同一日期(2010 年 11 月 15 日),只是区域性/区域设置不同。想象一下执行此操作所需的所有日期格式代码的 T-SQL 表示形式的大小。可能不是你想用什么来访问你的数据库... :)

因此,要回答您的问题:最好的选择是执行日期格式设置和其他 .net 擅长但无法在 .net 代码中转换为 T-SQL 的操作。在具有执行格式设置的属性的单独投影类中,或者通过将 L2E 查询投影到 .net 类型中,然后执行第二个 L2O(linq-to-objects)查询,该查询使用您可能想要执行的格式设置和其他转换投影到新类型中。

简短的回答:

分两步完成 - 一个执行 L2E 支持部分的 L2E 查询,另一个执行日期格式设置和其他最好在 .net 代码中完成的 L2O 查询......

//Linq-to-entities query to get the fullname, categoryname, and date
var query = from c in db.Contacts select new { c.FullName, c.Category.CategoryName, c.DateCreated };
//Linq-to-objects query (.AsEnumerable will separate the L2E from L2O part) that call date formatting methods and other stuff that isn't supported by L2E
var r = from c in query.AsEnumerable() select new { c.FullName, c.CategoryName, ShortDate = c.DateCreated.ToString("D") };

从此处复制的答案(msdn 论坛)

相关内容

  • 没有找到相关文章

最新更新