asp.net mvc 5 -在c#中将基类转换为派生类
本文关键字:基类 转换 派生 mvc net asp | 更新日期: 2023-09-27 18:02:17
我正在尝试将基类转换为派生类对象。见下面的代码,我有问题,当我转换。这是基本的东西,但挣扎。
[HttpGet]
[Route("/Edit/{Id}")]
public ActionResult Edit(int Id)
{
List<ClassA> Data = Ctx.GetClassAFromId(Id);
// Now Here I want convert ABC List<ClassA> to XyZ List<ClassA>
//How to do that?
return View(DataXYZ);
}
EF生成的模型
namespace ABC
{
public partial class ClassA
{
public string First_name { get; set; }
public string Last_Name { get; set; }
}
}
项目模型namespace XYZ
{
[MetadataType(typeof(ClassAMetadata))]
public partial class ClassA:ABC.ClassA
{
}
public class ClassAMetadata
{
[DisplayName(@"First Name")]
[Required]
public string First_name { get; set; }
[DisplayName(@"Last Name")]
[Required]
public string Last_Name { get; set; }
}
}
如何转换ABC。a班到xyz班。a班?
编辑:
我们正在做i18n项目。所以我们需要用不同的语言显示每个文本。但是我们的EF项目和web项目在不同的Namespace中。这就是我从基类
不能将List<BaseClass>
转换为List<DerivedClass>
可以使用linq:
listABC.Cast<XYZ.ClassA>.ToList()
但注意-这是O(n)
程序
尽管它们的名字相似,但它们是完全不同的类。就像你把它们叫做Foo
和Bar
一样
你需要一个方法来转换这些对象。它接受一个Foo
对象作为参数,然后返回一个等价的Bar
对象
public Bar Foo_To_Bar(Foo myFoo)
{
return new Bar() { Prop1 = myFoo.Prop1, Prop2 = myFoo.Prop2 };
}
差不多。如果你想在两个方向上进行转换,你可能还需要一个反过来的方法。
注意:如果类具有相同名称的属性,我建议您查看Automapper。它为你自动化了许多无聊的工作。
编辑
显然,您的Foo
继承自Bar
。这让事情变得更加复杂。当我有时间的时候,我会重写这个答案。
我没有看到一个用例让你的ViewModel (XYZ.ClassA) 派生自你的基础实体(ABC.ClassA)。你能解释一下为什么需要这个吗?我觉得你在滥用继承。
一般来说,您希望XYZ.ClassA
具有类型为ABC.ClassA
(或任何IEnumerable<ABC.ClassA>
变体)的属性,而不是继承它。
你能确认这是一个实际的要求,或者可以是问题的一部分,如果它解决了你的问题,可以改变吗?
EDIT -基于一个对象从另一个对象继承的事实,参见c#/。. NET Little Wonders:使用Cast()和OfType()来改变序列类型
几个选项:
1。
namespace ABC
{
public partial class ClassA
{
public ClassA(XYZ.ClassA classToConvert)
{
this.First_name = classToConvert.First_name,
this.Last_Name = classToConvert.Last_Name
}
public string First_name { get; set; }
public string Last_Name { get; set; }
}
}
使用:
var newClassA = new ABC.ClassA((XYZ.ClassA)classA)
列个清单:
List<ABC.ClassA> newClassAList = classAList.Select(p => new ABC.ClassA((XYZ.ClassA)p).ToList();
或者在没有上面构造函数的列表中使用对象初始化器
List<ABC.ClassA> newClassAList = classAList.Select(p => new ABC.ClassA{First_name = p.First_name, Last_Name = p.Last_Name}.ToList();
正如其他人提到的使用AutoMapper。
- 使用Nuget并添加AutoMapper到您的项目(和一些初始化代码)
创建您的地图:
Mapper.CreateMap<XYZ.ClassA, ABC.ClassA>();
映射你的对象:
var myABCClassA= Mapper.Map<XYZ.ClassA, ABC.ClassA>(myXYZClassA);
只要两个类的属性名匹配,这就是你需要的所有代码
我今天创建了这个
public static void Map<T1, T2>(this T1 obj1, T2 obj2) where T1 : class where T2 : class
{
IEnumerable<(PropertyInfo p1, PropertyInfo p2)> properties = typeof(T1).GetProperties()
.Join(typeof(T2).GetProperties(), o => o.Name, t => t.Name, (o, t) => (o, t));
foreach((PropertyInfo p1, PropertyInfo p2) in properties)
{
if (p1.CanWrite && p1.PropertyType == p2.PropertyType)
{
p1.SetValue(obj1, p2.GetValue(obj2));
}
}
}