在EntityFramework中手动分区DbSet

时间:2016-06-07 14:07:58

标签: c# .net entity-framework ef-code-first

我不太清楚这个问题的标题应该是什么,但现在是。

我正在尝试在.Net中设计一个Code-First模型,我希望自动生成DbSets。我有大约15个类,它们只是基于一个常量属性(string)而彼此不同。在应用程序的DbContext中,我有15个属性,每个属性相同但名称不同(适合它将存储的数据)。这种分离的原因在于性能。因此,如果我想要来自key1的课程的数据,我会查看相应的DbSet

所以这就是我现在对模特所拥有的:

public class MyClassKey1: MyClassBase
{
    public override string Key = "key1"
}

public class MyClassKey2: MyClassBase
{
    public override string Key = "key2"
}
// and so on this MyClassKey15 ..

MyClassBase仅确保每个子类重写属性Key。 ApplicationDbContext看起来像:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{

    public DbSet<MyClassKey1> Key1Objects { get; set; }
    public DbSet<MyClassKey2> Key2Objects { get; set; }
    // and so on till Key15Objects.. 
}

虽然这很合适,但我看不到自己为DataAcessLayer编写高效的代码。有没有更好的方法来实现这个?也许更好的设计模式或方法?

Update1 :我认为我需要的是一种模拟MS SQL提供的表分区的方法。我不会使用MS SQL服务器,或者提供开箱即用的表分区的数据库。有点像小型数据库,SQlite在手机等有限的硬件上。

1 个答案:

答案 0 :(得分:0)

我与合作伙伴和客户(合作伙伴)一样,他们都有账单地址,所以我的第一个方法是从像AddressEntity这样的东西中获得合作伙伴和客户。

过了一段时间,使用聚合而不是继承似乎要容易得多。我有一个带有Billing Addresses的表,而Partner有一个外键BillingAddresId到BillingAddress。客户具有相同的结构:

public class Partner
{
    public long Id { get; set; }
    public string NaturalKey { get; set; }

    // foreign key to address
    public long BillingAddressId { get; set; }
    public virtual BillingAddress BillingAddress { get; set; }

    // a partner has a collection of customers:
    public virtual ICollection<Customer> Customers { get; set; }
}

public class Customer : IId, ITerminable
{
    public long Id { get; set; }

    // foreign key to partner:
    public long PartnerId { get; set; }
    public virtual Partner Partner { get; set; }

    // foreign key to address
    public long BillingAddressId { get; set; }
    public virtual BillingAddress BillingAddress { get; set; }
}

public class BillingAddress
{
    public long Id { get; set; }
    public string FirstName { get; set; }
    public string Preposition { get; set; }
    public string Surname { get; set; }
    // etc
}

注意:因为您无法说明帐单邮寄地址是属于合作伙伴还是客户,因此帐单地址没有合作伙伴或客户的外键

public class MyDbContext : DbContext
{
    public DbSet<Partner> Partners { get; set; }
    public DbSet<Customer> Customers { get; set; }
    public DbSet<BillingAddress> Addresses { get; set; }
    ...
}

这样可以产生三个表:一个带有Billing Addresses,一个带有Partners,另一个带有Customers。每个合作伙伴和每个客户都将拥有一个外键,用于记帐地址表中的记录。只要合作伙伴或客户添加了填写的帐单邮寄地址,帐单邮寄地址就会自动添加到帐单邮寄地址表中,并将其ID分配给BillingAddressId。

public Partner CreatePartner(...)
{
    BillingAddress address = CreateAddress(...)
    return new Partner()
    {
        BillingAddress = address,
        OtherProperty = ...,
    };
}

public Partner AddPartner(...)
{
    Partner partnerToAdd = CreatePartner(...);
    // don't allow partners without addresses:
    if (partnerToAdd.BillingAddress == null) throw ...

    using (var dbContext = new MyDbContext();
    {
        var addedPartner = dbContext.Partners.Add(partnerToAdd);
        dbContext.Savechanges();
        return addedPartner;
    }
}

public Partner RetrievePartner(long partnerId)
{
    using (var dbContext = new MyDbContext();
    {
        return dbContext.Partners
            .Include(p => p.BillingAddress)
            .Single(p => p.Id == partnerId);
    }
}

include语句使得帐单地址包含在与检索合作伙伴数据的帐户相同的数据库查询中。