programing

Dapper 오류가 발생한 IEnumberable 컬렉션을 "class는 Dapper에서 지원하지 않습니다."로 삽입합니다.

yellowcard 2023. 5. 15. 21:27
반응형

Dapper 오류가 발생한 IEnumberable 컬렉션을 "class는 Dapper에서 지원하지 않습니다."로 삽입합니다.

네, 대퍼닷넷으로 레코드를 삽입하는 방법에 대한 질문여기저기 있습니다.하지만, 그 대답들은 유익하기는 하지만, 제가 올바른 방향으로 가는 것 같지는 않았습니다.다음은 SqlServer에서 MySql로 데이터를 이동하는 상황입니다.기록을 읽어 들입니다.IEnumerable<WTUser>쉬운 일이지만, 삽입물에 뭔가가 들어가지 않을 뿐입니다.첫째, '기록 이동 코드':

//  moving data
Dim session As New Session(DataProvider.MSSql, "server", _
                           "database")

Dim resources As List(Of WTUser) = session.QueryReader(Of WTUser)("select * from tbl_resource")


session = New Session(DataProvider.MySql, "server", "database", _
                      "user", "p@$$w0rd")

//    *edit* - corrected parameter notation with '@'
Dim strInsert = "INSERT INTO tbl_resource (ResourceName, ResourceRate, ResourceTypeID, ActiveYN) " & _
                "VALUES (@ResourceName, @ResourceRate, @ResourceType, @ActiveYN)"

Dim recordCount = session.WriteData(Of WTUser)(strInsert, resources)

//  session Methods
    Public Function QueryReader(Of TEntity As {Class, New})(ByVal Command As String) _
                                                            As IEnumerable(Of TEntity)
        Dim list As IEnumerable(Of TEntity)

        Dim cnn As IDbConnection = dataAgent.NewConnection
        list = cnn.Query(Of TEntity)(Command, Nothing, Nothing, True, 0, CommandType.Text).ToList()

        Return list
    End Function

    Public Function WriteData(Of TEntity As {Class, New})(ByVal Command As String, ByVal Entities As IEnumerable(Of TEntity)) _
                                                          As Integer
        Dim cnn As IDbConnection = dataAgent.NewConnection

        //    *edit* if I do this I get the correct properties, but no data inserted
        //Return cnn.Execute(Command, New TEntity(), Nothing, 15, CommandType.Text)

        //    original Return statement
        Return cnn.Execute(Command, Entities, Nothing, 15, CommandType.Text)
    End Function

cnn. 쿼리와 cnn.대퍼 확장 메서드 호출을 실행합니다.이제 WTUser 클래스(SqlServer의 'WindowsName'에서 MySql의 'ResourceName'으로 열 이름이 변경됨에 따라 두 속성이 동일한 필드를 가리킴):

Public Class WTUser
    //    edited for brevity - assume the following all have public get/set methods
    Public ActiveYN As String
    Public ResourceID As Integer
    Public ResourceRate As Integer
    Public ResourceType As Integer
    Public WindowsName As String
    Public ResourceName As String

End Class

저는 대퍼로부터 예외를 받고 있습니다: "WTUser는 Dapper에서 지원하지 않습니다."DataMapper(dapper)의 이 방법:

    private static Action<IDbCommand, object> CreateParamInfoGenerator(Type OwnerType)
    {
        string dmName = string.Format("ParamInfo{0}", Guid.NewGuid());
        Type[] objTypes = new[] { typeof(IDbCommand), typeof(object) };

        var dm = new DynamicMethod(dmName, null, objTypes, OwnerType, true); // << - here
        //    emit stuff

        //    dm is instanced, now ...
        foreach (var prop in OwnerType.GetProperties().OrderBy(p => p.Name))

이 시점에서 소유자 유형 =

시스템. 컬렉션.포괄적인.목록 1[CRM Back End.WTUser, CRMBE, Version=1.0.0.0, Culture=중립, 공개 키Token=filename]], mscorlib, Version=2.0.0, Culture=neutral, PublicKey토큰=b77a5c561934e089

OwnerType은 다음과 같아야 합니다.CRMBackEnd.WTUser...것은 아니다.List<CRMBackEnd.WTUser>수집 속성이 반복되고 있기 때문입니다.개수, 용량 등내가 뭘 놓친 거지?

갱신하다

내가 세션을 수정했다면.데이터 쓰기:

Public Function WriteData(Of TEntity As {Class, New})(ByVal Command As String, _
                                                      ByVal Entities As IEnumerable(Of TEntity)) _
                                                      As Integer
    Dim cnn As IDbConnection = dataAgent.NewConnection
    Dim records As Integer

    For Each entity As TEntity In Entities
        records += cnn.Execute(Command, entity, Nothing, 15, CommandType.Text)
    Next

    Return records
End Function

레코드는 잘 삽입되어 있습니다... 하지만 다음과 같은 예를 고려할 때 이것이 필요할 것이라고 생각하지 않았습니다.

connection.Execute(@"insert MyTable(colA, colB) values (@a, @b)",
    new[] { new { a=1, b=1 }, new { a=2, b=2 }, new { a=3, b=3 } }
  ).IsEqualTo(3); // 3 rows inserted: "1,1", "2,2" and "3,3"  

dapper-dot-net에서

방금 테스트를 추가했습니다.

class Student
{
    public string Name {get; set;}
    public int Age { get; set; }
}

public void TestExecuteMultipleCommandStrongType()
{
    connection.Execute("create table #t(Name nvarchar(max), Age int)");
    int tally = connection.Execute(@"insert #t (Name,Age) values(@Name, @Age)", new List<Student> 
    {
        new Student{Age = 1, Name = "sam"},
        new Student{Age = 2, Name = "bob"}
    });
    int sum = connection.Query<int>("select sum(Age) from #t drop table #t").First();
    tally.IsEqualTo(2);
    sum.IsEqualTo(3);
}

그것은 광고대로 작동합니다.다중 실행이 작동하는 방식을 몇 가지 수정했습니다(그래서 좀 더 빠르고 객체[]를 지원합니다).

내 생각에 당신은 당신의 모든 분야에서 더 나은 속성을 놓치고 있었기 때문에 문제가 있었던 것 같습니다.WTUser모든 매개 변수에는 판독기 속성이 있어야 합니다. 필드에서 이 속성을 가져오는 것을 지원하지 않습니다. 효율성을 유지하려면 복잡한 구문 분석 단계가 필요합니다.


지원되지 않는 매핑을 사용하여 dapper 매개 변수를 전달하는 것도 문제를 일으킨 추가 지점입니다.

예를 들어 다음 클래스는 매개 변수로 지원되지 않습니다.

class Test
{
   public int Id { get; set; }
   public User User {get; set;}
}

cnn.Query("select * from Tests where Id = @Id", new Test{Id = 1}); // used to go boom 

문제는 dapper가 SQL을 구문 분석하지 않았기 때문에 모든 속성이 param으로 설정될 수 있다고 가정했지만 다음에 대한 SQL 유형을 확인할 수 없었습니다.User.

최신 개정으로 이 문제가 해결되었습니다.

언급URL : https://stackoverflow.com/questions/6387904/inserting-an-ienumerablet-collection-with-dapper-errors-out-with-class-is-not

반응형