Silverlight 2 - การเพิ่มบันทึกฐานข้อมูลโดยใช้ WCF

ฉันกำลังสร้างแอปพลิเคชัน Silverlight 2 แบบง่ายๆ - สมุดเยี่ยม ฉันใช้ MSSQL เป็นแหล่งข้อมูล ฉันจัดการเพื่อโหลดข้อมูลแล้ว แต่ไม่พบวิธีเพิ่มแถว (ข้อความ) ใหม่ลงในฐานข้อมูล

ฉันรวบรวมข้อมูลอินเทอร์เน็ตทั้งหมดแล้ว แต่ไม่พบวิธีแก้ปัญหาที่ใช้งานได้ ตาราง SCMEssages มีสี่คอลัมน์ ได้แก่ MessageID, MessageDate, MessageAuthor และ MessageText ตอนนี้ฉันมีรหัสต่อไปนี้ในคลาส Service1 (ซึ่งใช้อินเทอร์เฟซ IService1) (แต่ใช้งานไม่ได้):

    public void SaveMessage(SCMessage message)
    {
        DataClasses1DataContext db=new DataClasses1DataContext();
        db.GetTable<SCMessage>().Attach(message);
        db.SubmitChanges();
    }

ในชั้นเรียนหลักฉันแค่เรียกวิธีนี้:

    private void SendBtn_Click(object sender, RoutedEventArgs e)
    {
        SCMessage sm = new SCMessage
                           {
                               MessageAuthor = NameTB.Text,
                               MessageDate = DateTime.Now,
                               MessageText = TextTB.Text
                           };
        newMessages.Add(sm);

        ServiceReference1.Service1Client client = new Service1Client();
        client.SaveMessageAsync(sm);
    }

ใครสามารถช่วยฉันได้บ้าง? ขอบคุณสำหรับข้อเสนอแนะใด ๆ !


person jkottnauer    schedule 23.02.2009    source แหล่งที่มา


คำตอบ (5)


ฉันไม่แน่ใจว่าฉันเข้าใจบริบทครบถ้วน (เช่น คุณควบคุมบริการ WCF และ/หรือฐานข้อมูลของคุณ) แต่คุณพิจารณาบริการข้อมูลของ ADO.Net หรือไม่ (หรือเรียกอีกอย่างว่า แอสโทเรีย) (http://msdn.microsoft.com/en-us/library/cc668792.aspx

คุณไม่จำเป็นต้องสร้างบริการเว็บให้ เพราะบริการนี้สร้างไว้สำหรับคุณแล้ว

โดยพื้นฐานแล้วมันเป็นวิธีที่ง่ายในการเข้าถึงข้อมูลของคุณจากภายใน Silverlight และยังสามารถทำการสืบค้นจากภายใน Silverlight ได้อีกด้วย

มีเอกสารอยู่บ้างแล้วในบล็อก ตัวอย่างเช่น: การเริ่มต้นอย่างรวดเร็วอยู่ที่นี่: http://michaelsync.net/2008/01/15/sumption-adonet-data-service-astoria-from-silverlight วิธีอัปเดตข้อมูลสามารถดูได้ที่นี่: http://michaelsync.net/2008/02/10/crud-operations-in-siverlight-using-adonet-data-service

ตัวอย่างการทำงานที่สมบูรณ์อยู่ที่นี่: http://www.silverlightdata.com/

โปรดทราบว่าในตัวอย่างจำนวนมากบนเว็บ พร็อกซี Silverlight ถูกสร้างขึ้นโดยใช้บรรทัดคำสั่ง ซึ่งไม่จำเป็นอีกต่อไป คุณสามารถทำได้โดยตรงจากภายใน VS โดยใช้ "เพิ่มการอ้างอิงบริการ" ไปยังโครงการของคุณและชี้ไปที่ ado ของคุณ บริการข้อมูล .net

หวังว่านี่จะช่วยได้สักหน่อย?

จิปเก

person Tjipke    schedule 23.02.2009
comment
ฉันเคยพบบทความเหล่านั้นมาก่อน แต่ไม่คิดว่าจะมีประโยชน์เพราะฉันต้องการแก้ไขด้วยวิธี WCF แต่ตอนนี้ดูเหมือนเป็นวิธีที่ง่ายกว่ามากสำหรับฉัน ฉันจะลองดู ขอบคุณมาก! ฉันจะโพสต์ผลลัพธ์ที่นี่ :-) - person jkottnauer; 24.02.2009

SCMessage ได้รับการตกแต่งด้วยแอตทริบิวต์ [DataContract] หรือเป็น [Serializable] หรือไม่ โปรดระบุคำจำกัดความของ SCMessage ให้เราทราบ

person Tad Donaghe    schedule 23.02.2009

SCMessage เป็นชื่อของคลาสข้อมูล - ฉันสร้างไฟล์จากเทมเพลต "Linq ถึง SQL Classes" (.dbml) แล้วลากและวางตาราง SCMessages ไปยัง Designer ตกแต่งด้วยแอตทริบิวต์ [DataContract] และฉันตั้งค่าคุณสมบัติโหมดอนุกรมของ DataContext เป็นทิศทางเดียว ดังนั้นเนื้อหาของคลาส SCMessage จึงถูกสร้างขึ้นโดยอัตโนมัติ แต่อย่างน้อยที่สุดก็มีเพียงบางส่วนเท่านั้น:

[Table(Name="dbo.SCMessages")]
[DataContract()]
public partial class SCMessage : INotifyPropertyChanging, INotifyPropertyChanged
{

    private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);

    private int _MessageID;

    private string _MessageAuthor;

    private string _MessageText;

    private System.DateTime _MessageDate;

#region Extensibility Method Definitions
partial void OnLoaded();
partial void OnValidate(System.Data.Linq.ChangeAction action);
partial void OnCreated();
partial void OnMessageIDChanging(int value);
partial void OnMessageIDChanged();
partial void OnMessageAuthorChanging(string value);
partial void OnMessageAuthorChanged();
partial void OnMessageTextChanging(string value);
partial void OnMessageTextChanged();
partial void OnMessageDateChanging(System.DateTime value);
partial void OnMessageDateChanged();
#endregion

    public SCMessage()
    {
        this.Initialize();
    }

    [Column(Storage="_MessageID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
    [DataMember(Order=1)]
    public int MessageID
    {
        get
        {
            return this._MessageID;
        }
        set
        {
            if ((this._MessageID != value))
            {
                this.OnMessageIDChanging(value);
                this.SendPropertyChanging();
                this._MessageID = value;
                this.SendPropertyChanged("MessageID");
                this.OnMessageIDChanged();
            }
        }
    }
person jkottnauer    schedule 23.02.2009

และนี่คือปัญหาเล็กน้อยกับแอสโทเรีย - มันไม่ได้ผลสำหรับฉัน ฉันติดตามบทช่วยสอนของ Michael Sync และทำการแก้ไขบางอย่าง เช่น การใช้ DataServiceQuery เนื่องจาก WebDataQuery ไม่มีอยู่ใน Astoria เวอร์ชันสุดท้าย เป็นต้น ฉันลงเอยด้วยตัวอย่างโค้ดสองชุด - อันแรกเกือบจะเหมือนกันกับสำเนาของอันใน Michael บทความของ Sync และบทความที่สองใช้แบบสอบถาม LINQ แทนวิธี CreateQuery (ฉันคิดว่าทั้งสองวิธีนี้นำไปสู่จุดสิ้นสุดเดียวกัน) นี่คือตัวอย่าง:

SilverchatDBEntities entity =
                new SilverchatDBEntities(new Uri("http://localhost:65373/WebDataService1.svc", UriKind.Absolute));
            entity.MergeOption = MergeOption.OverwriteChanges;
            DataServiceQuery<SCMessages> messages = entity.CreateQuery<SCMessages>("SCMessages");

            messages.BeginExecute(
                result =>
                    {
                        var mess = messages.EndExecute(result);
                        foreach (var mes in mess)
                        {
                            MessagesLB.Items.Add(mes.MessageAuthor);
                        }
                    },
                null);

สิ่งนี้ไม่ได้ทำอะไรเลย - ไม่มีข้อยกเว้นใด ๆ และไม่โหลด SCMessages ใด ๆ เช่นกัน ตัวอย่างที่สองมีดังนี้:

            SilverchatDBEntities entity =
            new SilverchatDBEntities(new Uri("http://localhost:65373/WebDataService1.svc", UriKind.Absolute));
        var query = (DataServiceQuery<SCMessages>) from m in entity.SCMessages select m;
        query.BeginExecute(new AsyncCallback(result =>
                                                 {
                                                     try
                                                     {
                                                         var mes = query.EndExecute(result);

                                                         foreach (var r in mes)
                                                         {
                                                             MessagesLB.Items.Add(string.Format("{0}; {1} - {2}",
                                                                                                r.MessageDate.
                                                                                                    ToString(
                                                                                                    "d/M hh:mm",
                                                                                                    CultureInfo.
                                                                                                        InvariantCulture),
                                                                                                r.MessageAuthor,
                                                                                                r.MessageText));
                                                         }
                                                     }
                                                     catch (Exception ex)
                                                     {
                                                         MessageBox.Show(ex.Message);
                                                     }
                                                 }), null);

อันนี้ส่งข้อยกเว้นที่ลูป 'foreach' - 'การอ้างอิงวัตถุไม่ได้ตั้งค่าเป็นอินสแตนซ์ของวัตถุ' ฉันไม่รู้ว่าปัญหาจะเป็นอย่างไร

person jkottnauer    schedule 24.02.2009

คริสตี้

ฉันยังไม่เห็นข้อผิดพลาดที่ชัดเจน ตามทฤษฎีแล้วมันควรจะได้ผล (ปัจจุบันฉันทำงานเกือบทุกวันกับข้อความค้นหาประเภทนี้ คำถามสองสามข้อ: 1. คุณสามารถใช้ fiddler2 เพื่อดูว่าเกิดอะไรขึ้น (ถ้าคุณไม่รู้ว่า fiddler คืออะไร google : -) และถ้าหลังจากนั้น คุณกำลังใช้ fiddler บน localhost โปรดเพิ่ม '." ใน url ในเบราว์เซอร์ (เช่น http:\localhost.:1234\mywebsitehostingsilverlight.aspx) -> ป้องกันการค้นหาโดย Google อื่นๆ) 2 คุณมีการติดตามสแต็กของอันที่สองที่สร้างข้อยกเว้นหรือไม่ 3. คุณได้ลองใส่เบรกพอยต์ในการโทรกลับของคุณ (ตัวอย่างแรก) เพื่อดูว่ามันถูกเรียกหรือไม่ และผลลัพธ์เป็นอย่างไร

หวังว่าคำถามเหล่านี้จะช่วยแก้ปัญหาได้เล็กน้อย

person Tjipke    schedule 25.02.2009
comment
ฉันเพิ่งลองใส่เบรกพอยต์ในการเรียกกลับตามที่คุณแนะนำ และจบลงด้วยข้อผิดพลาดนี้: 'ไม่สามารถโหลดประเภท 'SilverlightApplication1.ServiceReference1.SCMessage' จากชุดประกอบ 'SilverlightApplication1,...' ฉันคิดว่านี่อาจเป็นปัญหา... - person jkottnauer; 26.02.2009
comment
คุณมี SCMessage สองประเภทในโครงการของคุณหรือไม่? จากพร็อกซีที่สร้างโดยบริการข้อมูลและหนึ่งในบริการ WCF ดั้งเดิมของคุณ - person Tjipke; 27.02.2009
comment
ฉันไม่ทำเพราะฉันสร้างโซลูชันใหม่สำหรับการใช้บริการข้อมูล WCF จึงไม่เหลืออะไรเลย - person jkottnauer; 28.02.2009