كيفية استهلاك عمليات خدمة بيانات WCF في تطبيق Client .NET؟

StackOverflow https://stackoverflow.com/questions/4083547

سؤال

حسنًا ، أنا قادم جديد لخدمات البيانات و LINQ في حاجة ماسة إلى بعض التوجيهات. في غضون أيام قليلة ، واجهت العديد من العقبات غير المتوقعة وأنا عالق في يوم واحد. آمل أن تكون هذه مجرد إحباطات نموذجية لتعلم أداة جديدة.

لدي خدمة بيانات WCF لخدمة البيانات من جدول قاعدة بيانات SQL Server لإحداثيات GPS. على وجه الخصوص ، لدي طريقة تشغيل خدمة تتيح لك تحديد نطاق دقة وعطرية/خط الطول لإنتاج تمثيل أكثر عمومية للبيانات.

في متصفح الويب ، يبدو أنه يعمل كما هو متوقع. ومع ذلك ، عندما أحاول الاتصال بالعملية من تطبيق العميل الخاص بي ، تختلف القائمة التي يتم إرجاعها إلى العميل عن القائمة التي تم إنشاؤها بواسطة الخدمة.

سأستخدم أجزاء من الكود الخاص بي لشرح التفاصيل:

عملية خدمة البيانات:

    // This is my service operation that I need to call from my client app (see below). 
    // It should return an IEnumerable<Gps> (Gps is one of my Entity Model 
    // types) list of distinct GPS rounded to the number of decimal positions 
    // specified and within the range specified.
    [WebGet]
    public IEnumerable<Gps> GetGpsView(int decimalPlaces, decimal minLatitude, decimal minLongitude, decimal maxLatitude, decimal maxLongitude)
    {
        // I must first return a list of anonymous-type objects
        // because LINQ does not seem to allow me to construct my
        // Gps object within the query (one of those other issues
        // I had to tip-toe around).
        var list = (from g in this.CurrentDataSource.Gps
                    where g.Latitude >= minLatitude &&
                             g.Latitude <= maxLatitude &&
                             g.Longitude >= minLongitude &&
                             g.Longitude <= maxLongitude
                    select new
                    {
                        Id = 0,
                        Latitude = Math.Round(g.Latitude, decimalPlaces),
                        Longitude = Math.Round(g.Longitude, decimalPlaces)
                    }).Distinct().ToList();

        // Now that I have my results, I need to convert the items in the
        // list to my Gps entity object.
        IEnumerable<Gps> gpsList = list.ConvertAll<Gps>(item => new Gps
                            {
                                Id = item.Id,
                                Latitude = item.Latitude,
                                Longitude = item.Longitude
                            });

        return gpsList;
    }

إذا قمت بتصحيح الطريقة أعلاه (تشغيلها على الخادم الظاهري للمرئيات في Visual Studio) عند استدعاؤها من تطبيق العميل الخاص بي ، يبدو أن GPSList يحتوي على البيانات المناسبة قبل العودة إلى العميل مباشرة. باستخدام معلمات الاختبار الخاصة بي ، أحصل على قائمة تضم 200 كائنات GPS متميزة يتم تقريب قيمها إلى الأماكن العشرية التي أحددها.

ومع ذلك ، بمجرد إرجاع النتائج إلى طريقة الاتصال في تطبيق العميل الخاص بي ، لدي قائمة تضم 200 كائن GPS ، لكنها كلها نفس القيمة. لكي تكون محددة ، فإن القيمة المكررة هي القيمة الأخيرة في مجموعة النتائج المتوقعة. لقد أكدت ذلك من خلال استدعاء هذه العملية في متصفح الويب وعرض النتائج.

طريقة العميل:

// Partial class extension of code auto-generated by service reference.
public partial class HsiSideBySideEntities
{
    public List<Gps> GetGpsView(int decimalPlaces, decimal minLatitude, decimal minLongitude, decimal maxLatitude, decimal maxLongitude)
    {
        this.IgnoreMissingProperties = true;

        // Format my relative URI string.
        string uri = string.Format("/GetGpsView?decimalPlaces={0}&minLatitude={1}M&minLongitude={2}M&maxLatitude={3}M&maxLongitude={4}M", decimalPlaces, minLatitude, minLongitude, maxLatitude, maxLongitude);

        // If I debug both client and service at the same time, when I step over this
        // line, it does reach my data service - and as I mentioned above, on the
        // service end it appears to generate the correct results.
        List<Gps> gpsList = this.Execute<Gps>(new Uri(uri, UriKind.Relative)).ToList();

        // However, the results are returned to the client code, my list contains
        // duplicates of the last expected record.
        return gpsList;
    }
}

حاولت إزالة الجزء "tolist ()" من خط "Execute ()" ، لكن عندما أحاول عرض النتيجة المحددة في مصحح الأخطاء ، فإنه يظهر استثناءًا يقرأ ، "يتم دعم تعداد واحد فقط من خلال هذا غير قابل للضرب. "

بقدر ما أستطيع أن أقول ، فإن رمز العميل الخاص بي هو المشبوهة الأولى. بعد كل شيء ، يوضح كل اختبار آخر أن عملية خدمة البيانات الخاصة بي تنتج النتائج المطلوبة.

هل أحتاج إلى القيام بشيء مختلف للحصول على قائمة الكائنات غير المقابلة من خدمة البيانات؟

أفهم أن هناك خيار Createquery () ، لكنني قرأت أن Execute () هو الطريق الأكثر ملاءمة لهذا السيناريو.

هل كانت مفيدة؟

المحلول

ربما يكون ذلك بسبب هذا:

select new
{
    Id = 0,
    Latitude = Math.Round(g.Latitude, decimalPlaces),
    Longitude = Math.Round(g.Longitude, decimalPlaces)
}

أفترض أن خاصية المعرف لكيان GPS هي المفتاح الأساسي الخاص بك. في مثالك ، تقوم بتعيين معرف كل GPS الذي تم إرجاعه إلى الصفر. في مكتبة عميل خدمات بيانات WCF ، يتم التعامل مع الكيانات ذات المفتاح الأساسي نفسه على أنها نفس الحالة لأسباب تتبع التغيير ، وبالتالي تتصرف الرسوم البيانية للكائن كما تتوقع في بيئة موجهة نحو الكائنات المرجعية مثل .NET.

إذا لم تتمكن لسبب ما من منح كيانات GPS معرفًا فريدًا ، ففكر في استخدام GUID للمفتاح الأساسي.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top