【问题标题】:How to Serialize a class object and save it on to Multiple XML files如何序列化一个类对象并将其保存到多个 XML 文件中
【发布时间】:2018-03-16 12:24:48
【问题描述】:

我有一个像下面这样的 Employee 类

 public class Employee
    {
        public int EmployeeID { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
        public DateTime DOB { get; set; }
    }

我正在使用实体框架从数据库中检索员工数据,如下所示

using (var dbContext = new EmployeeEntities())
{
    List<Employee> employeeList = new List<Employee>();
    employeeList = dbContext.employee.Select(x => new Employee
                                        {
                                            EmployeeID = x.EmployeeID,
                                            Name = x.Name,
                                            Age = x.Age,
                                            DOB = x.DOB
                                        }).ToList();
}

然后我将列表序列化并保存为 XML 文件。

if (employeeList.Count > 0)
{
     XmlSerializer mySerializer = new XmlSerializer(typeof(List<Employee>));
     TextWriter myWriter = new StreamWriter("D:\\Employee.xml", true);
     mySerializer.Serialize(myWriter, employeeList);
     myWriter.Close();
}

我的要求是根据我指定的页面大小将结果集保存到多个 XML 文件中。例如,如果 Employee 表包含 536 行并且我的页面大小为 100,那么我应该将其保存在 6 个 XML 文件中,分别包含 100,100,100,100,100 和 36 行。我如何使用实体框架来实现这一点??

【问题讨论】:

标签: c# xml entity-framework serialization xml-serialization


【解决方案1】:

过去我用这个Batch 扩展方法做到了这一点:

public static class EnumerableExtensions
{
    /// <summary> 
    /// Splits the values in an enumerable by position into batches of the specified size 
    /// </summary> 
    public static IEnumerable<IEnumerable<T>> Batch<T>(this IEnumerable<T> items, int batchSize)
    {
        using (var e = items.GetEnumerator())
        {
            while (e.MoveNext()) // check before entering the loop 
            {
                yield return BatchOf(e, batchSize);
            }
        }
    }

    private static IEnumerable<T> BatchOf<T>(IEnumerator<T> e, int batchSize)
    {
        for (var i = 0; i < batchSize; i++)
        {
            if (i > 0 && !e.MoveNext()) // already checked once before entering the loop / so only check on subsequent iterations 
            {
                yield break;
            }
            yield return e.Current;
        }
    }
}

那么使用起来就很简单了:

int i = 0;
foreach (var batch in employeeList.Batch(100))
{
    XmlSerializer mySerializer = new XmlSerializer(typeof(List<Employee>));
    TextWriter myWriter = new StreamWriter($"D:\\Employee{i++}.xml", true);
    mySerializer.Serialize(myWriter, batch.ToList());
    myWriter.Close();
}

【讨论】:

    【解决方案2】:

    您可以使用.Skip().Take() 来解决问题。

    .Take() 将从列表中取出定义数量的项目,如果较少,它将全部取出。 .Skip() 将跳过定义的数量。

    通过使用tmp 变量,您可以关闭employeeList 并保存每个文件。

      if (employeeList.Count > 0)
            {
                int take = 100;
                int i = 0;
                while (employeeList.Any())
                {
                    i++;
                    var tmp = employeeList.Take(take)ToList();
                    employeeList = employeeList.Skip(take).ToList();
                    XmlSerializer mySerializer = new XmlSerializer(typeof(List<Employee>));
                    TextWriter myWriter = new StreamWriter("D:\\Employee"+i+".xml", true);
                    mySerializer.Serialize(myWriter, tmp);
                    myWriter.Close();
                }
            }
    

    【讨论】:

    • 但是请注意,如果您有很多记录,性能可能会受到影响...make-awesome.com/2010/08/…
    • 如果我遵循这种方法,我会收到以下异常。无法转换类型为“d__311[Employee]' to type 'System.Collections.Generic.List1[Employee]”的对象。
    • @raja_89 奇怪,它对我来说很好。我添加了 .ToList(),它应该可以修复类型不匹配。
    猜你喜欢
    • 2011-05-06
    • 1970-01-01
    • 1970-01-01
    • 2021-05-03
    • 2016-01-23
    • 1970-01-01
    • 2016-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多