ダッパについての問題

dapper map orm

質問

public class Profile
{
    public int ID { get; set; }

    public string Name { get; set; }

    public string Phone { get; set; }

    public string Address { get; set; }

    public ExtraInfo Extra { get; set; }
}

public class Topic
{
    public int ID { get; set; }

    public string Title { get; set; }

    public DateTime CreateDate { get; set; }

    public string Content { get; set; }

    public int UID { get; set; }

    public int TestColum { get; set; }

    public string Name { get; set; }

    public Profile Author { get; set; }

    public Attachment Attach { get; set; }
}

正しい

var list = conn.Query<Topic, Profile, Topic>(
            @"select top 3 
                T.ID,
                T.Title,
                T.CreateDate,
                P.Phone,
                P.Name
            from Topic as T
            inner join Profile P on T.UID = P.ID",
            (T, P) => { T.Author = P; return T; },
            null,
            null,
            true,
            "Phone");

SqlMapper.cs行で例外をスローする

var list = conn.Query<Topic, Profile, Topic>(
            @"select top 3 
                T.ID,
                T.Title,
                T.CreateDate,
                P.Name,
                P.Phone
            from Topic as T
            inner join Profile P on T.UID = P.ID",
            (T, P) => { T.Author = P; return T; },
            null,
            null,
            true,
            "Name");

今、私はトピックのプロパティ "名前"を削除し、それは正しいでしょう。

私はキーがSqlMapper.cs行1153にあると思う

int current = 0;
var splits = splitOn.Split(',').ToArray();
var splitIndex = 0;

Func<Type, int> nextSplit = type =>
{
    var currentSplit = splits[splitIndex].Trim();
    if (splits.Length > splitIndex + 1)
    {
        splitIndex++;
    }

    bool skipFirst = false;
    int startingPos = current + 1;
    // if our current type has the split, skip the first time you see it. 
    if (type != typeof(Object))
    {
        var props = DefaultTypeMap.GetSettableProps(type);
        var fields = DefaultTypeMap.GetSettableFields(type);

        foreach (var name in props.Select(p => p.Name).Concat(fields.Select(f => f.Name)))
        {
            if (string.Equals(name, currentSplit, StringComparison.OrdinalIgnoreCase))
            {
                skipFirst = true;
                startingPos = current;
                break;
            }
        }

    }

    int pos;
    for (pos = startingPos; pos < reader.FieldCount; pos++)
    {
        // some people like ID some id ... assuming case insensitive splits for now
        if (splitOn == "*")
        {
            break;
        }
        if (string.Equals(reader.GetName(pos), currentSplit, StringComparison.OrdinalIgnoreCase))
        {
            if (skipFirst)
            {
                skipFirst = false;
            }
            else
            {
                break;
            }
        }
    }
    current = pos;
    return pos;
};

"現在のタイプに分割がある場合は、最初にスキップします。"

"現在の型"の名前が "split"に等しいが、dbからこのフィールドを選択しなかった場合、dapperは例外をスローします。

これは設計上の問題ですか、正しく使用されていませんか?

受け入れられた回答

あなたの編集に基づいて、これは本当にこれがより良く扱われるべきシナリオであるように見えます。これはプロジェクトサイトのバグとして記録する価値があります。これはかなり微妙なので、これを修正する正しい方法を決めるにはいくつか考えが必要です。

それうまくいくように見え、表示するコードで失敗するのが難しいです。次のコードはうまくいきます(1.13コードベースでテスト済み):

public void TestSplitWithMissingMembers()
{
    var result = connection.Query<Topic, Profile, Topic>(
    @"select 123 as ID, 'abc' as Title,
             cast('01 Feb 2013' as datetime) as CreateDate,
             'def' as Phone, 'ghi' as Name",
    (T, P) => { T.Author = P; return T; },
    splitOn: "Phone").Single();

    result.ID.Equals(123);
    result.Title.Equals("abc");
    result.CreateDate.Equals(new DateTime(2013, 2, 1));
    result.Name.IsNull();
    result.Content.IsNull();

    result.Author.Phone.Equals("def");
    result.Author.Name.Equals("ghi");
    result.Author.ID.Equals(0);
    result.Author.Address.IsNull();
}

私が追加したのは:

public Profile Author { get; set; }

to Topic 、それ以外の場合はコードは同一です。 実際のコードとサンプルコードの間で問題が変更される可能性はありますか?調査してうれしいですが、私は正しいことを見ていることを知る必要があります。


人気のある回答

私は、あなたが「電話」で分割したときのあなたの唯一の問題は、あなたがP.Phoneを最初に選択すべきだと思うことです:

 @"select top 3 
                T.ID,
                T.Title,
                T.CreateDate,
                P.Phone,
                P.Name

            from Topic as T
            inner join Profile P on T.UID = P.ID",


ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ