簡體   English   中英

如何使serviceStack.ormlite或Dapper中的映射取決於列類型?

[英]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和С#想法的上下文中實現的?

如果您了解我想要的內容,請指明如何制作類似內容的方向。 非常感謝。

我不會讓BCA派生。 相反,我會讓他們擁有一個成員實例。 您仍然可以讓BC實現一些接口:

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返回BC實例:

List<IProcessA> items = dbResult.Select(a => a.DeviceType == "B" ? new B(a) : new C(a))
    .ToList();

如果要添加新的類型DE ,則需要將“ 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM