在我目前的系统中,我有两个具有几乎相同的属性集的EF对象,但由于各种原因,它们可以统一或加入以共享一些相同的结构。它实际上是个人细节,所以看起来有点像这样:
public partial class Person
{
public int PersonID { get; set; }
public string Title { get; set; }
public string Surname { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
// .. etc
}
public partial class Member
{
public int MemberID { get; set; }
public string Title { get; set; }
public string Surname { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
// .. etc
}
最终必须将这两种对象类型的混合写入同一文件,如下所示:
foreach (Person p in People)
{
StringBuilder lineBuilder = new StringBuilder();
lineBuilder.Append("\"");
lineBuilder.Append(p.PersonID.ToString());
lineBuilder.Append("\",\"");
lineBuilder.Append(p.Title);
lineBuilder.Append("\",\"");
lineBuilder.Append(p.Forename);
lineBuilder.Append("\",\"");
// etc...
}
foreach (Member m in Members)
{
StringBuilder lineBuilder = new StringBuilder();
lineBuilder.Append("\"");
lineBuilder.Append(m.MemberID.ToString());
lineBuilder.Append("\",\"");
lineBuilder.Append(m.Title);
lineBuilder.Append("\",\"");
lineBuilder.Append(m.Forename);
lineBuilder.Append("\",\"");
// etc...
}
这显然是一件坏事 - 它不仅重复代码,而且它依赖于两个循环,在输出中保持相同的列数,如果代码被更改,可能很容易被忽略。
没有创建一个中间对象并将字段映射到它 - 这实际上只是将问题转移到其他地方 - 是否有办法解决这个问题,这使我可以将其转化为单个循环?
答案 0 :(得分:4)
在两个实体上放置一个接口,让你的逻辑对接口而不是具体的类
答案 1 :(得分:1)
假设你因为使用DB first EF而陷入这两个实体,我可以想到三个建议:
使用AutoMapper将这两个对象映射到第三个类。在第三类中覆盖ToString()。如果您包含AutoMapper单元测试以验证映射,则您永远不必担心更改 - AutoMapper将选择它并且无法通过测试。
将数据库重构为具有“人员类型”字段的多态Person表,然后您只有一个具有人员类型字段的Person实体。
首先使用代码EF并拥有基础人员类或界面。
答案 2 :(得分:1)
你在这里做了两件事。您在引号中包装字段,并且您使用逗号连接一系列字符串。只需编写一个方法,为任意数量的任意字符串执行此操作:
public static string BuildLine(IEnumerable<string> fields)
{
return string.Join(",", fields.Select(WrapInQuotes));
}
private static string WrapInQuotes(string rawData)
{
return string.Format("\"{0}\"", rawData);
}
一旦你有了这个,你现在可以让你的每个类只提供他们的字段的集合,而不负责格式化它们的输出。
请注意,您似乎在此处写出了CSV文件。我的第一个建议是不要。只需使用现有的CSV编写器,即可以为您处理所有字符转义等等,这样您就不必这样做了。到目前为止,您还有一些事情尚未解决,包括其中包含换行符或引号的字段,或者您实际上不应引用转义每个字段的事实,而只是那些包含需要引用转义的字符(即换行符,如果你想支持多行字段或逗号)。
答案 3 :(得分:0)
为它创建一个接口(或抽象类)。
public interface IDetails
{
string Title;
string Surname;
string AddressLine1;
string AddressLine2;
}
public partial class Member : IDetails
{
//etc
}
public partial class Person : IDetails
{
//etc
}
答案 4 :(得分:0)
你可以使用界面,
public interface ISocialHuman{
public int PersonID { get; set; }
public string Title { get; set; }
public string Surname { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
}
public static void writeHumanSomewhere(ISocialHuman){
StringBuilder lineBuilder = new StringBuilder();
lineBuilder.Append("\"");
lineBuilder.Append(p.PersonID);
lineBuilder.Append("\",\"");
lineBuilder.Append(p.Title);
lineBuilder.Append("\",\"");
lineBuilder.Append(p.Forename);
lineBuilder.Append("\",\"");
}
但您应该更改ID名称。