-1

我正在尝试使用包含嵌套类数组的 LINQ 填充实例。我已经设法使用以下 LINQ 做到这一点。我还在选择中包含了构成实例的类。

    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; } 
}

这很有效,我可以使用WarrantYear[0]或访问值WarrantYear1。这在设计 UI 时有时很有用。但是,在这种情况下,我不需要该WarrantYear1属性,因为我将其转换为 JSON,并且不需要重复(或者想在网络上发送相同数据的两个版本)。我的问题是,如何编写选择语句来加载 WarrantYear 数组。或者我如何编写类,以便我可以将数组作为属性访问。我的解决方案不应包含类中的Warrant1, Warrant2, Warrant3属性EditableWarrantBook

4

2 回答 2

1

由于没有 Warrant1、Warrant2 和 Warrant3 属性,我无法让选择工作,我将其保留原样并重写了类,以便 JSON 序列化程序创建一个没有 Warrant1、Warrant2 和 Warrant3 属性的 JSON 实例。我使用了这篇文章的反射。为了澄清这个问题,我的第一次尝试是创建一个两倍大的 JSON 有效负载,因为 JSON 序列化程序同时创建了 Warrant1、Warrant2 和 Warrant3 结构,并再次创建了 Warrant[] 数组。使用仅使用 Warrant[] 数组的 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();
    }
于 2012-05-21T14:05:42.900 回答
0

问题是您试图将 SQL 世界(构建您的查询)与您的 CLR 世界(创建新对象)混合在一起。解决此问题的方法是将您的查询分解为初始数据获取查询(SQL 世界),然后枚举结果以转换为您的对象(CLR 世界):

因此,在 之后where 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 对象的属性(尽管我没有检查p1null)。

于 2012-05-18T20:15:34.607 回答