我有以下情况:
public JsonResult ChangeFilterList(int option)
{
var data = new[] { new { Text = "Unknown option", Value = -1 } };
switch (option)
{
case 2: data = _departmentnameRepository.All.Select(x => new { Text = x.DeptName, Value = x.Id }).ToArray();
break;
case 3: data = Session["projectid"] == null
? _assetSequenceRepository.All.Select(x => new { Text = x.AssetShotName, Value = x.Id }).ToArray()
: _assetSequenceRepository.FindBy(p => p.ProjectId == (int)Session["projectid"]).Select(x => new { Text = x.AssetShotName, Value = x.Id }).ToArray();
break;
default: data = _userRepository.All.Select(x => new { Text = x.DisplayName, Value = x.UserID }).ToArray();
break;
}
return Json(data, JsonRequestBehavior.AllowGet);
}
case2
和default
看起来不错,但在案例3(有条件)上抱怨:Cannot implicitly convert type 'AnonymousType#1[]' to 'AnonymousType#2[]'
。我不应该?:
能够决定类型,因为我已经为匿名提供了var data = new[] { new { Text = "Unknown option", Value = -1 } };
的蓝图。
解决方案:
@Darin Dimitrov答案很棒,但我希望对匿名类型进行一些测试(简单情况总是需要它)。
正如@Douglas所怀疑:我的assetSequenceRepository
正在提供id
long
而匿名Value
则支持int
而不是long
。由于C#编译器没有隐式地将long
强制转换为int
,我得到了错误。编译片段是:
public JsonResult ChangeFilterList(int option = 3)
{
var data = new[] { new { Text = "Unknown option", Value = long.MaxValue } };
switch (option)
{
case 2: data = _departmentnameRepository.All.Select(x => new { Text = x.DeptName, Value = (long)x.Id }).ToArray();
break;
case 3: data = Session["projectid"] == null
? _assetSequenceRepository.All.Select(x => new { Text = x.AssetShotName, Value = x.Id }).ToArray()
: _assetSequenceRepository.FindBy(p => p.ProjectId == (int)Session["projectid"]).Select(x => new { Text = x.AssetShotName, Value = x.Id }).ToArray();
break;
default: data = _userRepository.All.Select(x => new { Text = x.DisplayName, Value = (long)x.UserID }).ToArray();
break;
}
return Json(data, JsonRequestBehavior.AllowGet);
}
答案 0 :(得分:5)
您正在将编译器置于真实测试中。只需编写一个视图模型来结束其痛苦并使事情更明确:
public class MyViewModel
{
public int Value { get; set; }
public string Text { get; set; }
}
然后将LINQ查询投影到此视图模型,以避免使用条件运算符和匿名类型可能产生的任何歧义:
public ActionResult ChangeFilterList(int option)
{
var data = new[]
{
new MyViewModel { Text = "Unknown option", Value = -1 }
};
switch (option)
{
case 2: data = _departmentnameRepository
.All
.Select(x => new MyViewModel { Text = x.DeptName, Value = x.Id })
.ToArray();
break;
case 3: data = Session["projectid"] == null
? _assetSequenceRepository
.All
.Select(x => new MyViewModel { Text = x.AssetShotName, Value = x.Id })
.ToArray()
: _assetSequenceRepository
.FindBy(p => p.ProjectId == (int)Session["projectid"])
.Select(x => new MyViewModel { Text = x.AssetShotName, Value = x.Id })
.ToArray();
break;
default: data = _userRepository
.All
.Select(x => new MyViewModel { Text = x.DisplayName, Value = x.UserID })
.ToArray();
break;
}
return Json(data, JsonRequestBehavior.AllowGet);
}
答案 1 :(得分:4)
我的猜测是,您的FindBy
方法会返回其属性与您期望的类型不同的对象(例如int?
而不是int
)。尝试指定类型转换以确保您的匿名类型具有正确的定义:
case 3: data = Session["projectid"] == null
? _assetSequenceRepository.All.Select(x => new { Text = x.AssetShotName, Value = x.Id }).ToArray()
: _assetSequenceRepository.FindBy(p => p.ProjectId == (int)Session["projectid"]).Select(x => new { Text = (string)x.AssetShotName, Value = (int)x.Id }).ToArray();
break;
关键变化是:
new { Text = (string)x.AssetShotName, Value = (int)x.Id })
↖ explicit type casts ↗
答案 2 :(得分:0)
以下测试代码编译得很好:
public void Test(int option, string parameter)
{
var data = new[] { new { Text = "Unknown option", Value = -1 } };
switch(option)
{
case 2:
data = Enumerable.Range(1, 4)
.Select(x => new { Text = x.ToString(), Value = x })
.ToArray();
break;
case 3:
data = (new Random()).Next(2) % 2 == 1
? Enumerable.Range(1, 6)
.Select(x => new { Text = x.ToString(), Value = x })
.ToArray()
: Enumerable.Range(1, 2)
.Select(x => new { Text = x.ToString(), Value = x })
.ToArray();
break;
default:
data = Enumerable.Range(1, 3)
.Select(x => new { Text = x.ToString(), Value = x })
.ToArray();
break;
}
}
我只将您的存储库调用更改为Enumerable.Range()
和Select
lambda,以获取正确的string
/ int
属性值。
我猜,你已经显示出使用的不完全是你想要编译的代码。在您的真实代码中,您有一个具有不匹配名称的属性(例如,不正确的大小写)或不正确的类型。
您可以通过将鼠标指针悬停在ToArray()
电话上来尝试解决问题。工具提示上会打印a is new { string Text, int Value }
。