我被困在一个奇怪的问题上。我有一个看起来像这样的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.SBlindAmount
和hh.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 论坛)