如何根据列类型在serviceStack.ormlite或Dapper中进行映射?
例如,我有下一个课程:
//table A
abstract Class A
{
public ulong? id {get; set}
public string Name {get; set}
public string DeviceType {get; set}
abstract public void method()
}
//no table
Class B : A
{
public override void method()
{
//dependent on B implementation
}
}
//no table
Class C : A
{
public override void method()
{
//dependent on C implementation
}
}
从ORM我需要一些精简版:
List<A> items = orm.Must_Return_list_With_B_and_C_Instances_From_A_Table();
我如何看待这个逻辑:
function Must_Return_list_With_B_and_C_Instances_From_A_Table()
{
var items = new List<A>();
foreach(var row in rows)
{
if (row.DeviceType == "B")
{
items.Add(new B(row)); // mean mapping there
}
else if (row.DeviceType == "A")
{
items.Add(new C(row)); // mean mapping there
}
}
}
然后我可以:
- 使用下一个:
foreach(var item in items)
{
item.method(); // calls the right method of class B or C
}
- 如果我需要添加新的deviceType,我只实现D类:A并编辑映射器,不要触及全局程序逻辑。
这通常是在ORM和С#idea的背景下实现的?
如果您了解我的需求,请说明如何制作类似的方向。非常感谢。
答案 0 :(得分:2)
我不会B
或C
来自A
。相反,我会让他们拥有成员实例。您仍然可以B
和C
实现一些界面:
interface IProcessA
{
void Method();
}
class B : IProcessA
{
readonly A _a;
public B(A a)
{
_a = a;
}
public void Method()
{
// do something with _a
}
}
class C : IProcessA
{
readonly A _a;
public C(A a)
{
_a = a;
}
public void Method()
{
// do something different with _a
}
}
然后,您可以使用Linq将B
或C
的实例作为IProcessA
返回:
List<IProcessA> items = dbResult.Select(a => a.DeviceType == "B" ? new B(a) : new C(a))
.ToList();
如果您要添加新类型D
或E
,您可能希望将Select
中完成的工作移至您可以添加的方法或工厂以后。
答案 1 :(得分:1)
你觉得我觉得有点像Dapper。这样做并不是Dapper的工作。但是,为什么不引入DI容器,而不是自己编写工厂。以TinyIoC为例,您可以将B和C注册为接口A的命名实现。当另一个DeviceType出现时,您只需注册一个新实现即可开始营业。
public interface A
{
POCO poco { get; set; }
void MyMethod();
}
public class B : A
{
public void MyMethod()
{
throw new NotImplementedException();
}
public POCO poco { get; set; }
}
public class C : A
{
public void MyMethod()
{
throw new NotImplementedException();
}
public POCO poco { get; set; }
}
public class POCO
{
public ulong? id { get; set; }
public string Name { get; set; }
public string DeviceType { get; set; }
}
public class Program
{
public static void main()
{
var ctr = TinyIoCContainer.Current;
ctr.Register<A, B>("B");
ctr.Register<A, C>("C");
List<A> devices = new List<A>();
using (var db = new SqlConnection(Config.DefaultConnectionString))
{
db.Open();
List<POCO> queryResults = db.Query<POCO>("SELECT * FROM Devices").ToList();
foreach (var queryResult in queryResults)
{
// the magic step where we create the right type of A based on the value in column Name...
var newDevice = ctr.Resolve<A>(queryResult.Name);
newDevice.poco = queryResult;
devices.Add(newDevice);
}
}
}
}