1

我已经在互联网上搜索了这个答案,并询问了几位开发人员,但都没有找到答案。我有一个名为 StaffingPositionsDataContract 的类,我正在将模拟数据(现在)加载到 List<> 中并返回到页面。这很好用,但现在我需要根据屏幕上输入的另一个值列表过滤列表,作为 JSON 发送到该服务,然后反序列化为同一类的列表。请注意,用户可以过滤这些类成员中的任何一个,因此所有可能为空,或者一个可能为空,等等。这是服务方法:

   public List<StaffingPositionsDataContract> GetStaffingPosition(string searchFilters)
    {
        var filters = JsonConvert.DeserializeObject<List<StaffingPositionsDataContract>>(searchFilters);
        IList<StaffingPositionsDataContract> contracts = new StaffingPositionsDataContract().LoadMockData();

        if (searchFilters.Length > 4)
        {
            //Filter contracts here!
        }

        return contracts;
    }

这是要加载的 Mock 数据的 Data Contract 类:

[DataContract] [Serializable]
public class StaffingPositionsDataContract
{
    [DataMember(Order = 1)] public int PositionId { get; set; }
    [DataMember(Order = 2)] public string Series { get; set; }
    [DataMember(Order = 3)] public string BFY { get; set; }
    [DataMember(Order = 4)] public string BudgetStatus { get; set; }
    [DataMember(Order = 5)] public string DutyStation { get; set; }
    [DataMember(Order = 6)] public string OrgLocation { get; set; }
    [DataMember(Order = 7)] public string BudgetingEntity { get; set; }
    [DataMember(Order = 8)] public string SeriesTitle { get; set; }
    [DataMember(Order = 9)] public int PersonnelId { get; set; }
    [DataMember(Order = 10)] public string PositionStatus { get; set; }
    [DataMember] public int RecId { get; set; }

    public List<StaffingPositionsDataContract> LoadMockData()
    {
        List<StaffingPositionsDataContract> staffingposition = new List<StaffingPositionsDataContract>()
        {
            new StaffingPositionsDataContract() {RecId=1, PositionId = 12345, Series="", BFY="FY2010", BudgetStatus="Actual", DutyStation="", OrgLocation="", BudgetingEntity=""},
            new StaffingPositionsDataContract() {RecId=2, PositionId = 67891, Series="", BFY="FY2011", BudgetStatus="Actual", DutyStation="", OrgLocation="", BudgetingEntity=""},
            new StaffingPositionsDataContract() {RecId=3,PositionId = 12345, Series="", BFY="FY2010", BudgetStatus="Projected", DutyStation="", OrgLocation="", BudgetingEntity=""},
            new StaffingPositionsDataContract() {RecId=4,PositionId = 67892, Series="", BFY="FY2011", BudgetStatus="Projected", DutyStation="", OrgLocation="", BudgetingEntity=""},
            new StaffingPositionsDataContract() {RecId=5,PositionId = 987654, Series="", BFY="FY2010", BudgetStatus="Projected", DutyStation="", OrgLocation="", BudgetingEntity=""}
        };
        return staffingposition;
    }
}

请注意,过滤器将始终是一个包含一个、部分或所有值的列表。如果可以的话,请拯救我的理智和帮助!谢谢!

我应该早先指出,我真的希望这是一个通用函数,可以被任何这些类似的数据类(有很多)使用。

4

3 回答 3

1

我不会过滤你过滤的地方。我会将过滤器传递给集合的负载并在内部使用它,或者通过将这些标准传递给服务或数据库或类似的方法,或者通过强制每个对象在将其添加到集合之前根据标准验证自身。

public List<StaffingPositionsDataContract> GetStaffingPosition(string searchFilters)
{
    var filters = JsonConvert.DeserializeObject<List<StaffingPositionsDataContract>>(searchFilters);
    IList<StaffingPositionsDataContract> contracts = new StaffingPositionsDataContract().LoadMockData(searchFilters);

    return contracts;
}

[DataContract] [Serializable]
public class StaffingPositionsDataContract
{
    [DataMember(Order = 1)] public int PositionId { get; set; }
    [DataMember(Order = 2)] public string Series { get; set; }
    [DataMember(Order = 3)] public string BFY { get; set; }
    [DataMember(Order = 4)] public string BudgetStatus { get; set; }
    [DataMember(Order = 5)] public string DutyStation { get; set; }
    [DataMember(Order = 6)] public string OrgLocation { get; set; }
    [DataMember(Order = 7)] public string BudgetingEntity { get; set; }
    [DataMember(Order = 8)] public string SeriesTitle { get; set; }
    [DataMember(Order = 9)] public int PersonnelId { get; set; }
    [DataMember(Order = 10)] public string PositionStatus { get; set; }
    [DataMember] public int RecId { get; set; }

    public List<StaffingPositionsDataContract> LoadMockData(string searchfilters)
    {
        // filter the list returned here

        List<StaffingPositionsDataContract> staffingposition = new List<StaffingPositionsDataContract>()
        {
            new StaffingPositionsDataContract() {RecId=1, PositionId = 12345, Series="", BFY="FY2010", BudgetStatus="Actual", DutyStation="", OrgLocation="", BudgetingEntity=""},
            new StaffingPositionsDataContract() {RecId=2, PositionId = 67891, Series="", BFY="FY2011", BudgetStatus="Actual", DutyStation="", OrgLocation="", BudgetingEntity=""},
            new StaffingPositionsDataContract() {RecId=3,PositionId = 12345, Series="", BFY="FY2010", BudgetStatus="Projected", DutyStation="", OrgLocation="", BudgetingEntity=""},
            new StaffingPositionsDataContract() {RecId=4,PositionId = 67892, Series="", BFY="FY2011", BudgetStatus="Projected", DutyStation="", OrgLocation="", BudgetingEntity=""},
            new StaffingPositionsDataContract() {RecId=5,PositionId = 987654, Series="", BFY="FY2010", BudgetStatus="Projected", DutyStation="", OrgLocation="", BudgetingEntity=""}
        };
        return staffingposition;
    }
}
于 2009-06-08T17:17:56.883 回答
0

你是怎么过滤的?您是否排除了从 json 反序列化的合同?你在评估平等方面有问题吗?在这里解决这个问题有点困难。

使用 Linq 过滤一个列表和另一个列表非常容易:

var foo = new int[]{1,2,3,4,5};
var bar = new int[]{1,3,5};
var result = from x in foo where !bar.Contains(x) select x;

这导致包含 2、4 的结果。 您只需在数据合约中使用 Equals 方法来执行您的要求所要求的任何等效测试。

如果您的 UI 允许用户“创建”1 到 n 个要过滤的合同,并且您将其作为合同的集合(其中没有一个可能为空),这仍然有效。


回应 Zacho 的评论:

var foo = new string[]{"1","2","3","4","5"}; 
var bar = new string[]{"1","3",null,"5"};
var result = from x in foo where !bar.Contains(x) select x;

过滤器 enumerable--bar-- 包含空值。此功能有效。如果这个解决方案对你不起作用,Zacho,你就会遇到不同的问题。我猜这与平等比较有关。

于 2009-06-08T17:21:29.173 回答
0

将两个集合的项发送到 XElements,使每个属性成为 XAttribute。

然后您可以比较属性以找到匹配项,这很容易。

public class Customer
{
    public int CustomerId { get; set; }
    public string Name { get; set; }
    public string FavoriteColor { get; set; }

    // probably a better way to do this
    // just writing fast for demo
    public XElement ToXElement()
    {
        List<XAttribute> attributes = new List<XAttribute>();

        if (this.CustomerId != 0)
            attributes.Add(new XAttribute("CustomerId", this.CustomerId));
        if (this.Name != null)
            attributes.Add(new XAttribute("Name", this.Name));
        if (this.FavoriteColor != null)
            attributes.Add(new XAttribute("FavoriteColor", this.FavoriteColor));

        XElement result = new XElement("Customer", attributes);
        return result;
    }
}

然后比较一下......

List<Customer> source = new List<Customer>()
{ new Customer(){ CustomerId=1, FavoriteColor="Blue", Name="Alex" },
  new Customer(){ CustomerId=2, FavoriteColor="Green", Name="Bob" },
  new Customer(){ CustomerId=3, FavoriteColor="Blue", Name="Cindy" },
  new Customer(){ CustomerId=4, FavoriteColor="Red", Name="Darren" }
};
List<Customer> examples = new List<Customer>()
{ new Customer(){ FavoriteColor="Blue", CustomerId = 3},
  new Customer(){ Name="Darren"}
};

List<XElement> sourceElements = source.Select(c => c.ToXElement()).ToList();
List<XElement> exampleElements = examples.Select(c => c.ToXElement()).ToList();

//and now the query...
var query = sourceElements
  .Where(s => exampleElements
    .Any(ex => ex.Attributes()
      .All(exatt => s.Attribute(exatt.Name).Value == exatt.Value)
    )
  );

foreach(XElement x in query)
  Console.WriteLine(x);

还:

  • 如果您发送一个空示例(所有默认值),您将返回整个源列表。
  • 如果您没有发送示例(一个空列表),您将一无所获。
于 2009-06-08T18:23:18.827 回答