Как вы получаете DataContext объекта LINQ to SQL? - PullRequest
4 голосов
/ 15 июля 2011

В настоящее время это то, что у меня есть:

public partial class LinqToSqlEntity {
    public IQueryable<AnotherLinqToSqlEntity> AnotherLinqToSqlEntities {
        using(DataContext context = new DataContext) {
            return context.AnotherLinqToSqlEntities.Where(item => item.Property == SOME_VALUE);
        }
    }
}

Есть ли способ получить DataContext из this , чтобы мне не нужно было создавать новый DataContext?

Ответы [ 2 ]

2 голосов
/ 15 июля 2011

Извините, это невозможно. В этом случае объект или очередь не хранит прямой ссылки на контекст.

1 голос
/ 29 марта 2013

Вы можете добиться этого, используя отражение, выяснив, было ли подключено событие PropertyChanging, но считайте это хаком, и, возможно, вы можете избежать его использования с лучшим дизайном. В нашем случае это используется делегат detach_EntityName, в котором мы изменяем поведение Linq по умолчанию, заключающееся в удалении только внешнего ключа записи (установка его в ноль) с фактическим удалением из БД.

public static DataContext GetDataContextFromEntityObject(object entity) 
{
    // Use a reflection to get the invocaiton list.
    var o = (PropertyChangingEventHandler)entity.GetType().GetField("PropertyChanging", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(entity);
    var o = GetFieldValue(entity, "PropertyChanging");

    if (o == null) return null;
    var invocationList = o.GetInvocationList();
    if (invocationList != null)
    {
        // DataContext changes are tracked through StandardChangeTracker
        object changeTracker = (from i in invocationList where i.Target.GetType().FullName == "System.Data.Linq.ChangeTracker+StandardChangeTracker" select i.Target).FirstOrDefault();
        if (changeTracker != null)
        {
            object services = GetFieldValue(changeTracker, "services");
            return (DataContext)GetFieldValue(services, "context");
        }
    }

    return null;
}

private static object GetFieldValue(object instance, string propertyName)
{
    return instance.GetType().GetField(propertyName, BindingFlags.Instance | BindingFlags.NonPublic).GetValue(instance);
}
...