[英]How make mapping in serviceStack.ormlite or Dapper dependent on column type?
如何根據列類型在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和С#想法的上下文中實現的?
如果您了解我想要的內容,請指明如何制作類似內容的方向。 非常感謝。
我不會讓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作為IProcessA
返回B
或C
實例:
List<IProcessA> items = dbResult.Select(a => a.DeviceType == "B" ? new B(a) : new C(a))
.ToList();
如果要添加新的類型D
或E
,則需要將“ Select
完成的工作移到以后可以添加到的方法或工廠中。
我對Dapper的期望很高。 這不是Dapper的工作。 但是,為什么不引入自己的工廠,而不介紹自己的工廠呢? 例如,使用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);
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.