1

我正在尝试设置一个测试工具,我有一些数据想以 XML 格式包含在我的项目中,并将其加载到测试预设置方法中的业务对象中。

类结构是

public class DbUserChoice 
    { 
        public int Id { get; set; } 
        public string Description { get; set; } 
    } 
public class DbUserAmbition : DbUserChoice { } 
public class DbUserDiet : DbUserChoice { } 
public class DbUserEthnicity : DbUserChoice { } 
etc...

因此,有一个抽象基类 DbUserChoice,然后由用户拥有的所有不同类型的选择(总共 15 个)扩展。除了一个之外,所有这些都没有给类增加任何东西,只是逐字扩展它。

XML 结构是(部分)

<UserChoiceOptions> 
  <UserChoice ChoiceType="DbUserAmbition"> 
    <Choice>I'm content to just sit back and enjoy life</Choice> 
    <Choice>I have a few ambitions and dreams but keep my feet on the ground</Choice> 
    <Choice>I'm quite ambitious and driven in my career and personal life</Choice> 
    <Choice>I'm extremely driven to succeed and want the very best from life</Choice> 
  </UserChoice> 
  <UserChoice ChoiceType="DbUserBodyType"> 
    <Choice Gender="M">Slim</Choice> 
    <Choice Gender="M">Athletic and toned</Choice> 
    <Choice Gender="M">A healthy medium</Choice> 
    <Choice Gender="M">Muscular</Choice> etc... 

我想要某种可以将 DataType 传递给的通用方法,它会返回一个 IQueryable,其中包含映射到 XML 中该数据类型的选项,由上面的 UserChoice 节点上的“ChoiceType”鉴别器属性选择。

例如

var ambitions = TestUtil.ReadXMLObjects<DbUserAmbition>(xmlFilePath);

IQueryable<DbUserAmbition>用上述 4 个选项返回给我

15 种用户选择类型中有 14 种会以这种方式运行。唯一不同的是上面也提到的 DbUserBodyType,正如您所见,它在 Gender 的每条记录上都有一个附加属性。这是 DbUserBodyType 类上的一个新属性,它是向基类添加新记录的唯一派生类,并且还需要从该 XML 属性中填充该属性。

我一直在尝试使用 Linq to XML 来实现这一点,但我似乎无法完全正确。下面的代码给了我一个 XElements 列表,但我看不出如何在不使用混乱反射的情况下轻松干净地将其转换为 C# DbUserAmbition 对象列表。

var element = XElement.Load(_xmlPath);
            var typeName = typeof(T).Name;

            var nodes = from n in element.Elements("UserChoiceOptions/UserChoice/Choice")
                        where n.Parent.Attribute("ChoiceType").Value.Equals(typeName, StringComparison.CurrentCultureIgnoreCase)
                        select n;

任何的建议都受欢迎

4

1 回答 1

0

好吧,您可以通过声明一个从 xml 解析数据的方法来实现这一点:

public class DbUserChoice 
{ 
    public int Id { get; set; } 
    public string Description { get; set; } 

    public virtual void Parse(XElement node)
    {
        //assign properties from XElement here
        //override this method in DbUserBodyType to add additional logic
    } 
} 

然后您的查询将以:

return nodes.Select(n => { var x = new T(); x.Parse(n); return x; }).AsQueryable();

这将为您的通用方法添加一个限制T : DbUserChoice, new(),但这应该不是问题

于 2013-09-27T11:58:31.233 回答