سؤال

أشارك البيانات عبر خدمات RIA باستخدام نموذج عرض تقديمي أعلى فئات LINQ إلى SQL. على عميل Silverlight ، قمت بإنشاء اثنين من الكيانات الجديدة (الألبوم والفنان) ، وربطتهم ببعضهما البعض (إما بإضافة الألبوم إلى مجموعة ألبوم الفنان ، أو تعيين خاصية الفنان في الألبوم - إما عمل واحد) لهم إلى السياق ، وتقديم التغييرات.

على الخادم ، أحصل على مكالمتين إدراجين منفصلين - أحدهما للألبوم وواحد للفنان. هذه المعمتين جديدة ، لذا يتم تعيين قيم المعرف الخاصة بهم على قيمة int الافتراضية (0 - ضع في اعتبارك أنه بناءً على ديسيبل ، قد يكون هذا معرفًا صالحًا في DB) لأنه بقدر ما أعرف أنك لا تقوم بتعيين معرفات للكيانات الجديدة على العميل. كل هذا سيعمل بشكل جيد إذا كنت أقوم بنقل فصول LINQ إلى SQL عبر خدمات RIA الخاصة بي ، لأنه على الرغم من أن إدراج الألبوم يتضمن الفنان ويتضمن الفنان الألبوم ، وكلاهما كيان ويتعرف عليها سياق L2S. ومع ذلك ، مع كائنات نموذج العرض التقديمي المخصص ، أحتاج إلى تحويلها إلى LINQ إلى فئات SQL الحفاظ على الجمعيات في هذه العملية بحيث يمكن إضافتها إلى سياق L2S.

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

هل هذا ممكن ، أم يجب أن أتابع تصميمًا آخر؟

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

المحلول

إذا قمت بإنشاء جمعيات الوالدين والطفل الصحيحة ، فستحتاج فقط إلى تتبع علاقات العرض التقديمي المُدرج (PM)-العلاقات:

PM's:

public class Parent
{
    [Key]
    public int? ParentID { get; set; }

    [Include]
    [Composition]
    [Association("Parent_1-*_Child", "ParentID", "ParentID", IsForeignKey = false)]
    public IEnumerable<Child> Children { get; set; }
}

public class Child
{
    [Key]
    public int? ChildID { get; set; }

    [Include]
    [Association("Parent_1-*_Child", "ParentID", "ParentID", IsForeignKey = true)]
    public Parent Parent { get; set; }
}

تأكد من استخدام [التكوين] لإجبار WCF RIA على استدعاء طريقة insertChild على خدمة Domainservice.

Silverlight:

...
public Child NewChild(Parent parent)
{
    return new Child
                {
                    ParentID = parent.ParentID,
                    Parent = parent,
                };
}
...
public void SubmitChanges()
{
    DomainContext.SubmitChanges(SaveComplete, null);
}
...

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

خدمات Domainser على الخادم:

[EnableClientAccess]
public class FamilyDomainService : DomainService
{
    private readonly IDictionary<object, EntityObject> _insertedObjectMap;

    public void InsertParent(Parent parent)
    {
        ParentEntity parentEntity = new ParentEntity();

        ObjectContext.AddToParents(parentEntity);
        _insertedObjectMap[parent] = parentEntity;

        ChangeSet.Associate(parent, parentEntity, (p, e) => p.ParentID = e.ParentID;
    }

    public void InsertChild(Child child)
    {
        var childEntity = new ChildEntity();

        if (child.ParentID.HasValue) // Used when the Parent already exists, but the Child is new
        {
            childEntity.ParentID = child.ParentID.GetValueOrDefault();
            ObjectContext.AddToChildren(childEntity);
        }
        else // Used when the Parent and Child are inserted on the same request
        {
            ParentEntity parentEntity;
            if (child.Parent != null && _insertedObjectMap.TryGetValue(child.Parent, out parentEntity))
            {
                parentEntity.Children.Add(childEntity);
                ChangeSet.Associate(child, childEntity, (c, e) => c.ParentID = e.Parent.ParentID);
            }
            else
            {
                throw new Exception("Unable to insert Child: ParentID is null and the parent Parent cannot be found");
            }
        }

        _insertedObjectMap[child] = childEntity;

        ChangeSet.Associate(child, childEntity, (c, e) => c.ChildID = e.ChildID );
    }

    protected override bool PersistChangeSet()
    {
        ObjectContext.SaveChanges();
        _insertedObjectMap.Clear();
        return true;
    }
}

القطعتين المهمين هنا. أولاً ، يخزن "_insertedObjectMap" العلاقة بين الكيانات التي تم إدراجها حديثًا والتي لا تحتوي على مجموعة الهوية. نظرًا لأنك تقوم بذلك في معاملة ومكالمة واحدة إلى DB ، سيتم تعيين المعرف إلا بعد إدراج جميع الكيانات. عن طريق تخزين العلاقة ، يمكن للطفل PM العثور على إصدار الكيان من PM PM باستخدام قاعدة البيانات. تتم إضافة كيان الطفل إلى جمع الأطفال على كيان الوالدين ويجب على LINQTOSQL أو LINQTOENITYFRAMEWORK التعامل مع المفتاح الخارجي لك.

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

جاءت معلوماتي من changeet.associate () من: http://blogs.msdn.com/deepm/archive/2009/11/20/wcf-ria-services-presentation-model-explained.aspx

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