3

我决定使用 Dapper.net,因为它似乎只做我想做的事:映射,我不需要任何花哨的东西,我只是无聊地处理我的数据读取器和我的对象之间的映射。

我的问题 :

假设我有这些课程:

class Foo{
int ID;
string Name;
}
class Bar : Foo{
string FavoriteMoovie;
}

这些表:

Foo 
- ID
- Name

Bar
- FooID
- FavoriteMoovie

所以我想知道如何在同一个查询中选择我的 Foo 和 Bars ?

到目前为止我唯一的想法是

  • 选择所有不是 Bars 的 Foos
  • 然后选择所有酒吧

我不能使用“查询”方法的重载,因为这里只是用于映射关系。

4

2 回答 2

2

非常hacky,但这可能有效。

db.Query<Bar, object, Foo>("select * from Foo left join Bar on FooID = ID",
 (bar,ignore) => 
   bar.FavoriteMoovie == null ? bar : new Foo{ID = bar.ID, Name = bar.Name});

缺点是它创建了一些可以不用的中间对象。

其他选项是简单地选择Bar对象,然后使用相同的技巧过滤掉 Foos 或选择动态然后转换为正确的类。

就个人而言,我不会为了处理这个问题而查询两次,除非您允许使用NULLFavoriteMoovie,在这种情况下,您别无选择,只能使查询复杂化或选择两次。

于 2011-12-18T09:41:48.797 回答
1

在每个层次 TPH 一个表的情况下,很容易获得所有具体的子类,特别是如果 BaseClass 是抽象的

abstract class BaseValue
{
    public BaseValue()
        : this(0, 0, string.Empty)
    {
    }

    public BaseValue(int id, double value, string dimension)
    {
        Id = id;
        TypeName = GetType().Name;
        Dimension = dimension;
        _value = value;
    }

    protected double _value;

    public double RawValue
    {
        get { return _value;  }
    }

    public int Id { get; protected set; }

    public string TypeName { get; protected set; }

    public string Dimension { get; set; }

}

abstract class BaseValue<T> : BaseValue
    where T : struct
{
    public BaseValue()
        : this(0, default(T), string.Empty)
    { }

    public BaseValue(int id, T value, string dimension)
        : base(id, 0, dimension)
    {
        Value = value;
    }

    public T Value
    {
        get
        {
            if (typeof(T) == typeof(float))
                return (dynamic)(float)_value;
            else if (typeof(T) == typeof(bool))
                return (dynamic)(bool)(_value > 0 ? true : false);
            else if (typeof(T) == typeof(int))
                return (dynamic)(int)_value;
            else if (typeof(T) == typeof(TimeSpan))
                return (dynamic)TimeSpan.FromSeconds(_value);
            else if (typeof(T) == typeof(DateTime))
                return (dynamic)new DateTime((long)_value);
            else
                return (dynamic)_value;
        }
        set
        {
            if (typeof(T) == typeof(float))
                _value = (float)(object)value;
            else if (typeof(T) == typeof(bool))
                _value = (bool)(object)value ? 1 : 0;
            else if (typeof(T) == typeof(int))
                _value = (int)(object)value;
            else if (typeof(T) == typeof(TimeSpan))
                _value = ((TimeSpan)(object)value).TotalSeconds;
            else if (typeof(T) == typeof(DateTime))
                _value = ((DateTime)(object)value).Ticks;
            else
                _value = (double)(object)value;
        }
    }
}

class IntValue : BaseValue<int>
{
    public IntValue()
        : this(0, 0, string.Empty)
    { }

    public IntValue(int id, int value, string dimension)
        : base(id, value, dimension)
    { }
}

class BoolValue : BaseValue<bool>
{
    public BoolValue()
        : this(0, false, string.Empty)
    { }

    public BoolValue(int id, bool value, string dimension)
        : base(id, value, dimension)
    { }
}

class FloatValue : BaseValue<float>
{
    public FloatValue()
        : this(0, 0, string.Empty)
    { }

    public FloatValue(int id, float value, string dimension)
        : base(id, value, dimension)
    { }
}

class TimeSpanValue : BaseValue<TimeSpan>
{
    public TimeSpanValue()
        : this(0, TimeSpan.MinValue, string.Empty)
    { }

    public TimeSpanValue(int id, TimeSpan value, string dimension)
        : base(id, value, dimension)
    { }
}

class DateTimeValue : BaseValue<DateTime>
{
    public DateTimeValue()
        : this(0, DateTime.Now, string.Empty)
    { }

    public DateTimeValue(int id, DateTime value, string dimension)
        : base(id, value, dimension)
    { }
}

和存储库从 TPH 表中选择:

class Repository
{
    public IEnumerable<BaseValue> GetAll()
    {
        IEnumerable<BaseValue> values = null;

        using (SqlConnection cn = new SqlConnection(""))
        {
            cn.Open();

            const string query = "SELECT Id, TypeName, RawValue, Dimension FROM Values";

            values = cn.Query<BaseValue, object, BaseValue>(query,
                (value, ignore) =>
                {
                    BaseValue child = null;

                    if (value.TypeName == "IntValue")
                        child = new IntValue(value.Id, (int)value.RawValue, value.Dimension);
                    else if (value.TypeName == "BoolValue")
                        child = new BoolValue(value.Id, value.RawValue > 0, value.Dimension);
                    else if (value.TypeName == "FloatValue")
                        child = new FloatValue(value.Id, (float)value.RawValue, value.Dimension);
                    else if (value.TypeName == "TimeSpanValue")
                        child = new TimeSpanValue(value.Id, TimeSpan.FromSeconds(value.RawValue), value.Dimension);
                    else if (value.TypeName == "DateTimeValue")
                        child = new DateTimeValue(value.Id, new DateTime((long)value.RawValue), value.Dimension);

                    return child;
                });

            cn.Close();
        }

        return values;
    }
}
于 2016-08-23T17:10:23.243 回答