C# Linq Select中的嵌套数组
我试图用包含嵌套类数组的LINQ填充实例。我已经用下面的LINQ实现了这一点。我还将构成实例的类包括在select中C# Linq Select中的嵌套数组,c#,linq,C#,Linq,我试图用包含嵌套类数组的LINQ填充实例。我已经用下面的LINQ实现了这一点。我还将构成实例的类包括在select中 select new EditableWarrantBook { Id = p1.id, Comment = p1.EntryComment, WarrantYear1 = new BookYear { StatusYear = p2.StatusYear, Status =
select new EditableWarrantBook {
Id = p1.id,
Comment = p1.EntryComment,
WarrantYear1 = new BookYear {
StatusYear = p2.StatusYear,
Status = p2.Status,
},
WarrantYear2 = new BookYear {
StatusYear = p3.StatusYear,
Status = p3.Status,
},
WarrantYear3 = new BookYear {
StatusYear = p4.StatusYear,
Status = p4.Status,
}
}
public class EditableWarrantBook
{
public int Id { get; set; }
public string Comment { get; set; }
public BookYear[] WarrantYear = new BookYear[3];
public BookYear WarrantYear1
{
get { return WarrantYear[0]; }
set { WarrantYear[0] = value; }
}
public BookYear WarrantYear2
{
get { return WarrantYear[1]; }
set { WarrantYear[1] = value; }
}
public BookYear WarrantYear3
{
get { return WarrantYear[2]; }
set { WarrantYear[2] = value; }
}
}
public class BookYear
{
public int? StatusYear { get; set; }
public string Status { get; set; }
}
这样我可以使用
warranceyear[0]
或warranceyear1
访问值。这在设计UI时有时很有用。但是,在本例中,我不需要warranceyear1
属性,因为我正在将其转换为JSON,并且不需要重复(或者希望在网络上发送相同数据的两个版本)。我的问题是,如何编写select语句来加载数组。或者如何编写类,以便可以作为属性访问数组。我的解决方案不应包含EditableWarrantBook
类中的warrans1、warrans2、Warrant3
属性。问题在于,您试图将SQL世界(构建查询)与CLR世界(创建新对象)混合。解决此问题的方法是将查询分解为初始数据获取查询(SQL world),然后枚举结果以转换为对象(CLR world):
因此,在之后,其中p1.SaleYear==2009
,添加以下内容:
select new { p1, p2, p3, p4 })
.AsEnumerable()
.Select(tr => new EditableWarrantBook
{
Id = tr.p1.id,
Comment = tr.p1.EntryComment,
WarrantYear = new[] {
tr.p2 == null ? (BookYear)null : new BookYear // EDITED LINE
{
StatusYear = tr.p2.StatusYear,
Status = tr.p2.Status,
},
tr.p3 == null ? (BookYear)null : new BookYear // EDITED LINE
{
StatusYear = tr.p3.StatusYear,
Status = tr.p3.Status,
},
tr.p4 == null ? (BookYear)null : new BookYear // EDITED LINE
{
StatusYear = tr.p4.StatusYear,
Status = tr.p4.Status,
}}
}).ToList();
如果要保持查询语法,只需将其更改为:
result = from tr in
(/*Select up to the AsEnumerable call above)*/).AsEnumerable()
select new EditableWarrantBook
{
/* Initialization code supplied above */
}
编辑:所以我再一次修改了这个例子。看起来您要返回的其中一个值是null,因此我添加了null检查以确保您没有访问null对象的属性(尽管我没有检查
p1
是否为null)。因为我无法在没有保证的情况下使select工作1,我保持原样并重写了这个类,这样JSON序列化程序就可以创建一个JSON实例,而不需要warrans1、warrans2和Warrant3属性。我使用了文章中的反射。为了澄清这个问题,我的第一次尝试是创建一个JSON有效负载,它的大小是必须的两倍,因为JSON序列化程序同时创建了ARSURK1、ARSURK2和ARSUR3结构以及ARSURK[]数组。用一个基类重写这个类,只使用arrance[]数组就可以得到JSON结果,这满足了我的Web服务的接口要求
namespace my.Models
{
public class WarrantBook
{
public int Id { get; set; }
public string Comment { get; set; }
BookYear[] warrantYear = new BookYear[3];
public BookYear[] WarrantYear
{
get { return warrantYear; }
set { warrantYear = value; }
}
}
public class EditableWarrantBook : WarrantBook
{
public BookYear WarrantYear1
{
get { return WarrantYear[0]; }
set { WarrantYear[0] = value; }
}
public BookYear WarrantYear2
{
get { return WarrantYear[1]; }
set { WarrantYear[1] = value; }
}
public BookYear WarrantYear3
{
get { return WarrantYear[2]; }
set { WarrantYear[2] = value; }
}
}
public class BookYear
{
public int? StatusYear { get; set; }
public string Status { get; set; }
}
public static class Ext
{
public static void CopyProperties(this EditableWarrantBook source, WarrantBook destination)
{
// Iterate the Properties of the destination instance and
// populate them from their source counterparts
PropertyInfo[] destinationProperties = destination.GetType().GetProperties();
foreach (PropertyInfo destinationPi in destinationProperties)
{
PropertyInfo sourcePi = source.GetType().GetProperty(destinationPi.Name);
destinationPi.SetValue(destination, sourcePi.GetValue(source, null), null);
}
}
}
}
使用WCF REST Web服务
[WebGet(UriTemplate = "GetWarrant?id={s}&user={user}")]
public WarrantBook GetWarrant(string s, string user)
{
int id;
if (int.TryParse(s, out id))
{
EditableWarrantBook model = SessionWarrantBook.One(p => p.Id == id);
model.CheckedOutBy = user; // need to add checkout code
WarrantBook jsonModel = new WarrantBook();
model.CopyProperties(jsonModel);
return jsonModel;
}
return new WarrantBook();
}
你想用所有的连接实现什么?没有一个实际使用CookSaleStatus对象中的任何值…连接不是问题的一部分,但是我根据你的评论简化了一点。我不想把事情搞混,但有时忽略它也会让人困惑。我尝试了上面的方法,它可以编译,但我得到了下面的运行时错误。“数组类型的BooYix[]不能在查询结果中初始化。请考虑使用‘Stasy.CycEng.No.List.1[BLabLa.BooYe]’。”该消息对我没有帮助。@李嘉图-基于这个答复,似乎您可以使用<代码> .AsvaseBable()/<代码>修复问题。尝试从P4在List3.Debug TimeType().asQueEnable()中尝试<代码>。?没有帮助,显示相同的错误消息。我的另一个选择是保留select原样,并尝试创建一个受保护的基类,其中warrans1、warrans2和Warrant3是受保护的。然后使用一个子类来屏蔽受保护的属性,并使用它来创建JSON。但我也不明白,这就是为什么我要寻求帮助。看起来我在整体上越来越深了。谢谢你的帮助。在做了SPFiredrake建议的改变后,我再次尝试了上述方法。编译,但我知道我得到一个空引用。也许我的课不对?我使用的是我给出的答案的版本。虽然我现在有了工作代码,但我宁愿不使用反射并按照SPFiredrake的建议来做,但我就是无法让它工作。谢谢,成功了。我感谢你抽出时间告诉我怎么做。因为你花了时间,我学到的不仅仅是如何解决我最初的问题。非常感谢。