2014-08-29 6 views
8

नहीं कहा जा रहा है, मैं ओरेकल डेटाबेस में वस्तुओं को लोड/जारी रखने के लिए डैपर का परीक्षण कर रहा हूं, और ओरेकल के ग्रिड स्टोरेज को प्रबंधित करने के लिए मुझे SqlMapper.TypeHandler<Guid> की आवश्यकता है। जब डेटाबेस से एक Guid स्तंभ लोड हो रहा है पार्स विधि कहा जाता है, लेकिन जब मैं एक Guid पैरामीटर मैं निम्नलिखित अपवाद का उपयोग कर एक एसक्यूएल बयान पर अमल करने का प्रयास:डैपर टाइप हैंडलर.SetValue() को

System.ArgumentException बिना क्रिया था; संदेश = मान अपेक्षित सीमा के भीतर नहीं गिरता है। स्रोत = Oracle.DataAccess।

डीबग में मैं देख सकता हूं कि डेटाबेस से मेरी कक्षा लोड करते समय मेरे हैंडलर की पार्स() विधि को कॉल किया जा रहा है, लेकिन SetValue() mdethod नहीं है।

कोड अपवाद पुन: पेश करने

नीचे
CREATE TABLE foo (id  RAW (16) NOT NULL PRIMARY KEY, 
        name VARCHAR2 (30) NOT NULL); 

INSERT INTO foo (id, name) VALUES (SYS_GUID(), 'Bar'); 

COMMIT; 

using System; 
using System.Linq; 
using Dapper; 
using Oracle.DataAccess.Client; 

namespace Program 
{ 
    public class Foo 
    { 
     public Guid Id { get; set; } 
     public string Name { get; set; } 
    } 

    class GuidTypeHandler : SqlMapper.TypeHandler<Guid> 
    { 
     public override Guid Parse(object value) 
     { 
      Console.WriteLine("Handling Parse of {0}", value); 

      var inVal = (byte[])value; 
      byte[] outVal = new byte[] { inVal[3], inVal[2], inVal[1], inVal[0], inVal[5], inVal[4], inVal[7], inVal[6], inVal[8], inVal[9], inVal[10], inVal[11], inVal[12], inVal[13], inVal[14], inVal[15] }; 
      return new Guid(outVal); 
     } 

     public override void SetValue(System.Data.IDbDataParameter parameter, Guid value) 
     { 
      Console.WriteLine("Handling Setvalue of {0}", value); 

      var inVal = value.ToByteArray(); 
      byte[] outVal = new byte[] { inVal[3], inVal[2], inVal[1], inVal[0], inVal[5], inVal[4], inVal[7], inVal[6], inVal[8], inVal[9], inVal[10], inVal[11], inVal[12], inVal[13], inVal[14], inVal[15] }; 
      parameter.Value = outVal; 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      SqlMapper.AddTypeHandler<Guid>(new GuidTypeHandler()); 
      var conn = new OracleConnection(Resources.ConnectionString); 
      var def = new CommandDefinition("select id, name from foo"); 

      conn.Open(); 

      var foo = conn.Query<Foo>(def).First(); 
      Console.WriteLine(foo.Id + "; " + foo.Name); 

      foo.Name = "New Bar"; 

      def = new CommandDefinition(
       "UPDATE foo SET name = :name WHERE id = :id", 
       parameters: new { ID = foo.Id, NAME = foo.Name }); 

      var rows = conn.Execute(def); 
      Console.WriteLine("{0} rows inserted", rows); 

      Console.ReadLine(); 
     } 
    } 
} 
+0

क्या आपने कभी यह पता लगाया कि इसे कैसे काम किया जाए? जब मैं कस्टम ऑब्जेक्ट्स की एक सरणी को एक क्वेरी में पास करने का प्रयास करता हूं, तो मुझे एक समान समस्या का सामना करना पड़ रहा है (उदाहरण के लिए, "मेरा चयन करें जहां आईडीटेबल आईडी = किसी भी (: आईडी)" टाइप करें (: ids) == टाइपऑफ (myType [])) –

+0

कोई भाग्य नहीं, यह गिथब पर डैपर मुद्दों की सूची में क्वेरी को दोबारा पोस्ट करने लायक हो सकता है। – Bertol

उत्तर

0

मैं नेट Guid वर्ग के चारों ओर एक आवरण लिख कर इस समस्या के लिए काम किया है। आदर्श नहीं है क्योंकि आप अपने डीटीओ कक्षाओं में रैपर के साथ समाप्त होते हैं लेकिन यह काम करता है।

आवरण वर्ग:

public class OracleGuid 
{ 
    private Guid dotNetGuid; 

    public OracleGuid(Guid guid) 
    { 
     this.dotNetGuid = guid; 
    } 

    public OracleGuid(Byte[] byteArray) 
    { 
     this.dotNetGuid = new Guid(byteArray); 

    } 

    public Guid InternalGuid { get { return dotNetGuid; } } 
} 

हैंडलर वर्ग:

public class OracleGuidHandler : SqlMapper.TypeHandler<OracleGuid> 
{ 
    public override OracleGuid Parse(object value) 
    { 
     return new OracleGuid((byte[]) value); 
    } 

    public override void SetValue(System.Data.IDbDataParameter parameter, OracleGuid value) 
    { 
     parameter.Value = value.InternalGuid.ToByteArray(); 
    } 
} 

एक डीटीओ वर्ग कि आवरण वर्ग का उपयोग करता है:

public class FooDto 
{ 
    public OracleGuid Id { get; set; } 
    public string Name { get; set; } 
} 

नोट मैं रॉ उपयोग कर रहा हूँ (16) ओरेकल में इन्हें स्टोर करने के लिए, ओरेकल गिड्स में निर्मित नहीं।

संपादित ऐसा लगता है कि यह एक बग हो सकता है और निर्धारित किया गया है हो सकता है: https://github.com/StackExchange/dapper-dot-net/issues/253। ऐसा नहीं लगता है कि उसने इसे NuGet पैकेज में अभी तक बनाया है, इसलिए मैंने अभी तक इसे आजमाया नहीं है।

संबंधित मुद्दे