我陷入了一个奇怪的问题。我有一个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)
一部分。 hh.SBlindAmount
和hh.BBlindAmount
是浮点值。我想使用String.Format
,因为0.10
缩短为0.1
,并且我使用字符串格式就像我想要的那样。但我得到一个例外'The invocation of the constructor on type 'PokerRecord.View.CashGameGeneralUC' that matches the specified binding constraints threw an exception.' Line number '60' and line position '18'.
。当我删除string.format并输入一些“常规”字符串时,一切正常......任何人都知道为什么?
答案 0 :(得分:2)
我认为你正在尝试做什么(将特定浮点数格式化为字符串),你想要.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
然后使用string.Format:
定义Get Limitprivate 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返回预先格式化的字符串。
可能有更好的方法来做我正在做的事情,但是,遇到你遇到的同样的问题,这就是我解决它的方式。
答案 1 :(得分:1)
我刚才想到的另一个答案,以及我可能更愿意这样做的方式。我只是将这些原始值存储在ViewModel中,然后将Limit属性更改为仅根据这些值创建字符串:
public string Limit { get { return string.Format("{0:0.00}/{1:0.00}", SmallBlind, BigBlind); } }
修改强>
我会用这种方式加入我的推理 - 它是非破坏性的。但是,如果您的ViewModel不会发生太大变化,或者您知道将来永远不需要BigBlind / SmallBlind属性,那么这可能是过度或完全没有必要。
答案 2 :(得分:1)
此问题是您尝试执行的操作与SQL不兼容。您可能需要先在临时对象中获取数据,然后执行简单的转换到所需的对象。或者,您可能希望将该对象的原始值和另一个属性仅用于显示目的,这将以您喜欢的任何格式返回原始值。
答案 3 :(得分:1)
答案很长:
有些东西无法从CLR方法很好地转换为TSQL。日期格式化是一个很好的例子,因为.ToString(string s),. TooShort ......等方法依赖于大量特定于语言环境的设置来格式化最终结果。 (分隔符,不同日期部分的顺序,使用的日历时代,月/日名称等)。 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支持的部分,一个L2O查询执行日期格式化和其他最好用.net代码完成...
//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") };
从here(msdn论坛)
复制的答案