Доступ к LINQ-2-SQL DataContext в классе сущностей

Есть ли простой способ получить доступ к DataContextклассу сущностей linq2sql.

Я пытаюсь создать что-то вроде, EntitySetно я не могу понять, как у EntitySetнего есть доступ к контексту, который создал объект сущности в первую очередь.

Я хочу иметь обычный класс сущностей linq2sql с возможностью доступа к классу, DataContextкоторый его создал. Я знаю, что это возможно, потому что, когда у вас есть класс сущностей с первичным ключом, linq2sql дает вам возможность загрузить все дочерние элементы без создания нового DataContext.

15.12.2008 16:31:25
5 ОТВЕТОВ

В основном нет.

EntitySet<T>Класс имеет внутреннее Sourceсвойство, присвоенные данные контекст, который , как он попадет на данных по требованию. Однако для самих классов данных нет ничего похожего.

Однако я считаю, что Entity Framework имеет гораздо больший доступ к этому за счет принудительной иерархии объектов.

В отличие от Entity Framework, LINQ-to-SQL (по замыслу) может использоваться с обычными, невосприимчивыми к постоянству классами - поэтому он не предполагает, что у него есть доступ к данным такого типа.

3
15.12.2008 20:34:00

Класс Entity не должен знать о контексте данных как об отображении таблицы, но контекст данных знает все сущности и свойства соединения.

Вы можете связываться с дочерней таблицей через класс родительского объекта из-за отношения объекта, а не через контекст данных

Класс контекста данных будет использоваться в конце, где потребляются сущности, я не вижу необходимости, чтобы сущности были осведомлены о контексте,

Если вы можете сказать конкретный сценарий, мы можем попробовать другой подход.

1
5.04.2009 06:10:07
У меня та же проблема, и, хотя я понимаю ваш аргумент по этому поводу (поверьте мне, я за это), у меня есть реальная потребность в этом. В некоторых наших частичных классах сущностей мы добавили некоторые свойства, которые должны запрашивать базу данных на основе свойства их сущности, чтобы получить некоторую коллекцию других сущностей, которые не связаны напрямую с SQL Server. Это действительно ужасно, потому что мы создаем новый контекст данных при вызове этих свойств (некоторые из них в цикле).
Thiago Silva 18.04.2010 04:02:31

Я точно знаю, что вы имеете в виду. Предполагается, что мы должны выполнять наши вычисления / проверку в частичном классе сущности, но если у сущности нет доступа к текстовому тексту данных, то сколько мы можем сделать? Например, в моем объекте SalesOrder при изменении адреса «Отправлять» SalesOrder должен запросить базу данных, чтобы выяснить, применяется ли налог к ​​этому состоянию / почтовому индексу. Я боролся с этим некоторое время, но сегодня я сломался и пошел по уродливому методу, но пока все хорошо. По сути, все, что я делаю, - это создаю свойство «Context» в моем частичном классе и устанавливаю его с помощью datacontext при каждом создании объекта.

Partial Class SalesOrder
    Private moContext As L2S_SalesOrdersDataContext

    Friend Property Context() As L2S_SalesOrdersDataContext
        Get
            Return moContext
        End Get
        Set(ByVal value As L2S_SalesOrdersDataContext)
            moContext = value
        End Set
    End Property
...

YMMV, особенно если вы отделяете свои сущности.

0
4.05.2009 06:27:07

По сути, вы можете сделать это с небольшим количеством взлома. DataCOntext присоединяет StandardChangeTracker к вашей сущности:

            DataContext context = null;
            object changeTracker = (из i в o1.GetInvocationList (), где i.Target.GetType (). FullName == "System.Data.Linq.ChangeTracker + StandardChangeTracker" select i.Target) .FirstOrDefault ();
            if (changeTracker! = null) // DataCOntext отслеживает наши изменения через StandardChangeTracker
            {
                объект services = Reflector.GetFieldValue (changeTracker, "services");
                context = (DataContext) Reflector.GetFieldValue (services, "context");
            }

Где Reflector.GetFieldValue равно

        открытый статический объект GetFieldValue (экземпляр объекта, строка propertyName)
        {
            return instance.GetType (). GetField (propertyName, BindingFlags.Instance | BindingFlags.NonPublic) .GetValue (instance);
        }
0
10.02.2010 21:41:04

Я просто должен был сделать то же самое. Вот мое решение (хотя, вероятно, не самый лучший, но, по крайней мере, довольно элегантный):

Во-первых, создайте интерфейс для всех ваших сущностей для реализации, который наследуется от INotifyPropertyChanging. Это используется для подключения некоторых методов расширения и обеспечения отличной реализации нашей реализации. В моем случае интерфейс называется ISandboxObject:

public interface ISandboxObject : INotifyPropertyChanging
{
    // This is just a marker interface for Extension Methods
}

Затем создайте новый статический класс, который будет содержать метод расширения для получения DataContext. Это достигается путем поиска обработчика событий в LINQ Change Tracker, прикрепленном к событию INotifyPropertyChanging.PropertyChanging. Как только мы нашли трекер изменений, мы можем получить DataContext оттуда:

    /// <summary>
    /// Obtain the DataContext providing this entity
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static DataContext GetContext(this ISandboxObject obj)
    {
        FieldInfo fEvent = obj.GetType().GetField("PropertyChanging", BindingFlags.NonPublic | BindingFlags.Instance);
        MulticastDelegate dEvent = (MulticastDelegate)fEvent.GetValue(obj);
        Delegate[] onChangingHandlers = dEvent.GetInvocationList();

        // Obtain the ChangeTracker
        foreach (Delegate handler in onChangingHandlers)
        {
            if (handler.Target.GetType().Name == "StandardChangeTracker")
            {
                // Obtain the 'services' private field of the 'tracker'
                object tracker = handler.Target;
                object services = tracker.GetType().GetField("services", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(tracker);

                // Get the Context
                DataContext context = services.GetType().GetProperty("Context").GetValue(services, null) as DataContext;
                return context;
            }
        }

        // Not found
        throw new Exception("Error reflecting object");
    }

Теперь у вас есть хороший метод расширения, который предоставит вам DataContext из любого объекта, реализующего ISandboxObject. Пожалуйста, добавьте еще несколько ошибок, прежде чем использовать его в гневе!

6
12.03.2010 17:18:34