3

我正在编写一个应用程序,我们需要将一个基本实体扩展到许多不同的事物(例如员工、车辆等)。设计是这样的,有一个实体表和一个具有特定类型值的第二个表,例如,员工将有一个 ID 号,但车辆将有一个登记号。

我继承了数据上下文中生成的类实体,但在我的存储库中进行转换时遇到了问题。这样做的正确方法是什么?

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;
    }

强制转换在单一方法中失败,因此我返回 null。我的理解是,您不能从基类定义显式或隐式运算符?如何将基类 Linq 结果转换为继承的 Employee 类,同时仍保持其数据库状态以便我可以提交更改?

4

3 回答 3

1

使用 LINQ-to-SQL,继承可以通过两种方式工作:

  • 单个表的鉴别器(不适合,因为您的数据不是同质的)
  • 基类/多表(不是说这在 dbml 中不受支持 - 仅当您手动编写类时)

LINQ-to-SQL 不支持多表继承(即具有来自多个表的数据的单个对象)。实体框架可以,但更复杂;您在 EF 中使用.Cast<T>and.OfType<T>来根据子类型进行转换/过滤。

你可能想看看:

这里基类的目的是什么?如果它添加了行为,那么您可以编辑 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作用吗?

于 2009-01-30T09:20:37.470 回答
0

感谢您的输入,将查看一些建议...

帐户实体背后的想法是,到目前为止,该站点只需要处理员工,但将来他们可能希望将车辆等添加到系统中,该系统用于将成本分配给实体,因此为此目的,员工是处理方式与车辆相同。

这个想法是员工和车辆需要他处理相同的内容以在数据库等中进行引用,但需要关于它们的稍微不同的信息。这是一个复杂的设计,只是因为他们想稍后添加额外的类型但不需要升级数据库......

但是,在我的代码中,我想谈论的是员工而不是通用实体类型(使控制器、视图等在 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));
    }
于 2009-01-30T10:34:41.470 回答
0

如何将基类 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();
    }
}
于 2009-01-30T20:39:02.110 回答