Наследование класса Linq to SQL и приведение результата запроса linq - PullRequest
3 голосов
/ 30 января 2009

Я пишу приложение, в котором нам нужно будет расширить базовую сущность на несколько разных вещей (например, сотрудник, транспортное средство и т. Д.). Конструкция такова, что есть таблица сущностей и вторая таблица с типоспецифичными значениями, например, у сотрудника будет идентификационный номер, а у транспортного средства будет регистрационный номер.

Я унаследовал от объекта класса, созданного в контексте данных, но у меня возникли проблемы с приведением в моем хранилище. Как правильно это сделать?

public class cAccountEmployee : cAccountEntity
{
    public string id_number
    {
        get
        {
            try
            {
                return this.cAccountEntityValues.Single(e => e.type == 1).value;
            }
            catch (Exception)
            {
                return "";
            }
        }

        set
        {
            try
            {
                this.cAccountEntityValues.Single(e => e.type == 1).value = value;
            }
            catch (Exception)
            {
                this.cAccountEntityValues.Add(new cAccountEntityValue()
                                            {
                                                accountentity_id = this.id,
                                                cAccountEntity = this,
                                                type = 1,
                                                value = value
                                            });
            }
        }
    }

}

Тогда в моем хранилище (ничего не наследует)

public IEnumerable<cAccountEmployee> All(int accountholder_id)
    {
        return db.cAccountEntities.Where(e => e.accountholder_id == accountholder_id).OrderBy(a => a.name).Cast<cAccountEmployee>();
    }

    public cAccountEmployee Single(int id)
    {
        return db.cAccountEntities.Single(a => a.id == id) as cAccountEmployee;
    }

Приведение завершается неудачно в одном методе, и поэтому я получаю нулевое значение. Насколько я понимаю, вы не можете определить явные или неявные операторы из или в базовый класс? Как получить результат преобразования Linq базового класса в унаследованный класс Employee, сохраняя при этом его состояние базы данных, чтобы я мог отправлять изменения?

Ответы [ 3 ]

1 голос
/ 30 января 2009

В LINQ-to-SQL может работать наследование двумя способами:

  • дискриминатор для одной таблицы (не подходит, так как ваши данные не однородны)
  • базовый класс / мульти-таблица (не то, что это не поддерживается в dbml - только если вы пишете классы вручную)

LINQ-to-SQL не поддерживает наследование нескольких таблиц (т. Е. Один объект с данными из нескольких таблиц). Entity Framework делает, но является более сложным; вы используете .Cast<T> и .OfType<T> в EF для приведения / фильтрации на основе подтипов.

Возможно, вы захотите взглянуть на:

Какова цель базового класса здесь? Если это добавляет поведение, то вы можете отредактировать dbml, чтобы указать общий базовый класс для всех ваших сущностей. Если он имеет свойства данных , он становится сложнее.

Лично я бы просто так не поступил ... Я бы оставил отдельные классы для разных типов и правильно использовал бы контекст данных, используя отдельные таблицы для каждого типа:

public IEnumerable<Employee> All(int accountholder_id)
{
    return db.Employees.Where(e => e.accountholder_id == accountholder_id)
        .OrderBy(a => a.name);
}

public Employee Single(int id)
{
    return db.Employees.Single(a => a.id == id);
}

Итак - можете ли вы уточнить, что cAccountEntity делает здесь?

0 голосов
/ 30 января 2009

Как получить результат Linq базового класса для приведения к унаследованному классу Employee

Это не уныние, это уныние.

Я думаю, вы не понимаете приведение или, возможно, тип экземпляра против ссылочного типа.

public class Animal { }
public class Zebra : Animal { }

public class Zoo
{
    public void ShowZebraCast()
    {
        Animal a = new Animal();
        Zebra z = (Zebra)a;
    }
}

System.InvalidCastException: Невозможно привести объект типа «Животное» к типу «Зебра».

Таким же образом, у вас есть экземпляр Entity, который вы не можете снизить, чтобы использовать ссылку Employee против него.

Вы можете конвертировать типы, но тогда вам нужно указать метод конвертации.

public partial class Animal { }
public class Zebra : Animal { }
//in another file
public partial class Animal{
  public Zebra ToZebra(){
    return new Zebra() { //set Zebra properties here.
    };
  }
}


public class Zoo
{
    public void ShowZebraConvert()
    {
        Animal a = new Animal();
        Zebra z = a.ToZebra();
    }
}
0 голосов
/ 30 января 2009

Спасибо за ввод, рассмотрим некоторые предложения ...

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

Идея состоит в том, что работнику и транспортному средству нужно обращаться с ними одинаково для ссылок в БД и т. Д., Но им потребуется немного другая информация о них. Это сложный дизайн только потому, что они хотят добавить дополнительные типы позже, но без необходимости обновлять БД ...

Однако в моем коде я хочу поговорить о сотруднике, а не об универсальном типе сущности (сделать контроллер, представление и т. Д. Намного проще в приложении mvc). Поскольку вы не можете предоставить пользовательское преобразование из базового в производный класс, я пропустил его наследование и вместо него использовал следующее решение. Немного более громоздко, но работает ... Дайте мне знать, если кто-нибудь сможет найти лучший способ сделать это.

public class cAccountEmployee
{
    private cAccountEntity entity;

    public int id
    {
        get
        {
            return this.entity.id;
        }
        set
        {
            this.entity.id = value;
        }
    }

    public string name
    {
        get
        {
            return this.entity.name;
        }
        set
        {
            this.entity.name = value;
        }
    }

    public int accountholder_id
    {
        get
        {
            return this.entity.accountholder_id;
        }
        set
        {
            this.entity.accountholder_id = value;
        }
    }

    public System.Data.Linq.EntitySet<cAccountEntityValue> cAccountEntityValues
    {
        get
        {
            return this.entity.cAccountEntityValues;
        }
    }

    public cAccountHolder cAccountHolder
    {
        get
        {
            return this.entity.cAccountHolder;
        }
    }

    public cAccountEmployee()
    {
        this.entity = new cAccountEntity();
    }

    public cAccountEmployee(cAccountEntity entity)
    {
        this.entity = entity;
    }

    public string id_number
    {
        get
        {
            try
            {
                return this.entity.cAccountEntityValues.Single(e => e.type == 1).value;
            }
            catch (Exception)
            {
                return "";
            }
        }

        set
        {
            try
            {
                this.entity.cAccountEntityValues.Single(e => e.type == 1).value = value;
            }
            catch (Exception)
            {
                this.entity.cAccountEntityValues.Add(new cAccountEntityValue()
                                            {
                                                accountentity_id = this.id,
                                                cAccountEntity = this.entity,
                                                type = 1,
                                                value = value
                                            });
            }
        }
    }
}

//In the repository
public cAccountEmployee Single(int id)
    {
        return new cAccountEmployee(db.cAccountEntities.Single(a => a.id == id));
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...