简体   繁体   中英

SQL DBGeography second insert fails

This one is a strange one. I am trying to save a polygon from Google maps into MS SQL, via an MVC controller. The problem is that the first time I do it, it works, the second time it gives me the error:

The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect. Parameter 3 ("@2"): The supplied value is not a valid instance of data type geography. Check the source data for invalid values. An example of an invalid value is data of numeric type with scale greater than precision.

I am using EntityFramework 6.1.3, code first. The error appears on the commit line below:

var newPoly = new GenericPolygon()
                {
                    Name = webShape.Name,
                    PolyShape = shapePolygon,
                    IsEnabled = true,
                    IsDeleted = false
                };
                _unitOfWork.PolygonRepository.Add(newPoly);
                _unitOfWork.Commit();

The SQL table structure is the same as the class except that it has an int ID identity column as well, and the name is a varchar(255). The PolyShape column is of type geography.

The shapePolygon variable is defined like this, with the class adding a read-only property called "LongLat", which is used to switch from the Google LatLong to the MS LongLat format:

var shapePolygon = DbGeography.PolygonFromText("POLYGON((" + webShape.LongLat + "))", 4326);

The commit line itself calls the db context save method (I'm using UoW pattern to cut down on code):

this.context.SaveChanges();

I can't for the life of me figure out why it works once, and then not again, unless I restart my VS (running VS 2013 with IIS Express - SQL 2008 R2 Enterprise on a server).

Any help or pointers would be appreciated :-)

I seem to have narrowed down on the issue, and whilst it is more of a workaround than an answer this may help someone else.

The issue is the version of SQL Server, namely SQL 2008 R2 10.50.4000. I migrated my database to SQL Server 2012 build 11.0.5058, after which the code worked, every time.

Hope this helps someone!

I just had this and solved it by reversing the points in the polygon. Apparently SQL Server is left handed with these things or something.

So instead of having a string concatenation like strGeog += string.Format("{0} {1}, ", latlong[0], latlong[1]); I changed it to:

foreach (XmlNode xnPoly in xmlPolyList)
{
    strGeog = "";
    firstlatlong = null;

    if (xnPoly["coordinates"] != null)
    {
        latlongpairs = xnPoly["coordinates"].InnerText.Replace("\n", "").Split(' ');

        foreach (string ll in latlongpairs)
        {
            latlong = ll.Split(',');

            if (firstlatlong == null) firstlatlong = latlong;

            strGeog = string.Format("{0} {1}, ", latlong[0], latlong[1]) + strGeog;
        }
    }
    if (strGMPoly.Length > 0)
    {
        strGeog = strGeog.Substring(0, strGeog.Length - 2); //trim off the last comma and space
        strGeog = "POLYGON((" + string.Format("{0} {1} ", firstlatlong[0], firstlatlong[1]) + strGeog + "))"; // conversion from WKT needs it to come back to the first point.
    }
    i++;

    dbPCPoly = new PostCodePolygon();
    dbPCPoly.geog = DbGeography.PolygonFromText(strGeog, 4326);

    LocDB.PostCodePolygons.Add(dbPCPoly);
    LocDB.SaveChanges();
    Console.WriteLine(string.Format("Added Polygon {0} for Postcode ({1})", dbPCPoly.PCPolyID, dbPC.PostCodeName));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM