更改实体映射到另一个"未知"表在运行时 [英] Change entity map to another "unknown" table at runtime

查看:190
本文介绍了更改实体映射到另一个"未知"表在运行时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须写一个C#应用程序与旧的应用程序创建和编程和维持一个SQL Server数据库中运行。应用程序创建新表,每年年产权是在表名。它创建可以根据用户已应用中创建节的数目的变化的表的数目。所以,我有像Cwx_DRyz表(相当自我解释...),其中WX,可部分,YZ将是今年的工作。表的基团的例子可以是:

I have to write a C# application that works with a SQL server database created and mantained by an old application. The application creates new tables each year and the "year property" is in the table name. The number of tables it creates may vary depending of the number of "sections" that the user has created inside the application. So, I have to work with tables like Cwx_DRyz (quite self explanatory...), where "wx" can be the section, and "yz" would be the year. An example of group of table could be:

C01_DR07

C01_DR08

C01_DR09

C02_DR08

C02_DR09

C03_DR06

C04_DR12

和所有这些表可以表示,例如,客户端。他们会从不同的部分和年,但客户端具有相同的结构的客户端。

And all of those tables could represent, for example, clients. They would be clients from different sections and years, but clients with the same structure.

我的问题是:我能处理所有这些表,并在运行时改变从一个映射到另一个客户端实体?该标题说未知,因为我不知道在运行之前的表

My question is: Can I have a Client entity to handle all those tables and change the mapping from one to another at runtime? The title says "unknown" because I don't know the tables before runtime.

最类似的问题,我发现是的实体框架图多个表以一个实体和答案是使用表格每个具体类型的继承 ,但它不是我的情况非常有用

The most similar question I have found is Entity Framework map multiple tables to one entity and the answer is to use the "Table Per Concrete Type Inheritance", but it is not useful for my case.

PS:EF版本4.3.1和VS2010

PS: EF version 4.3.1 and VS2010

编辑:该表没有主键......他们中的大多数都被supossed有唯一值(整数或字符串)列

The tables don't have primary keys... Most of them have columns that are supossed to have unique values (integer or string).

推荐答案

如果您使用代码第一只要你想,你可以创建一个映射。这也与现有数据库的工作,如果映射您已经创建匹配的数据库。

If you use "code first" you could create a mapping as you want. This also works with existing databases when the mapping you have created match the database.

所以每当你创建一个环境,你可以建立字符串(表名)要映射到

So whenever you create a context you can build the string (tablename) you want to map to.

有些codesamples为代码第一,你怎么能启动:

Some codesamples for "code first" and how you could start:

的DbContext:

The DbContext:

public DbSet<YourEntity> YourEntities { get; set; }
...

// this is called when the db gets created and does the configuration for you => maybe not needed in your case
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    ConfigurationRegistrar configurationRegistrar = modelBuilder.Configurations;

    new GeneralEntitiesConfiguration(configurationRegistrar);
}



GeneralEntitiesConfiguration是用来处理配置类IM,无非就是一个帮手它看起来像:

GeneralEntitiesConfiguration is a class im using to handle the configurations, nothing more than a helper which looks like:

public class GeneralEntitiesConfiguration
{
    public GeneralEntitiesConfiguration(ConfigurationRegistrar configurationRegistrar)
    {
        configurationRegistrar.Add(new YourEntityConfiguration());
        //and additional configurations for each entity, just to splitt it a bit and have it more read and maintenance able
    }
}

YourEntityConfiguration是一类在那里我有这个实体的所有配置:

YourEntityConfiguration is a class where i have all the configurations for this entity:

public class YourEntityConfiguration : EntityTypeConfiguration<YourEntity>
{
    public YourEntityConfiguration ()
    {
        ToTable("WhatEverYouLike"); // here you can do any magic to map this entity to a table, just make sure that your properties are mapped to the correct colums
        Property(entity => entity.Id).HasColumnName("YouColumnName");

        //and here you also have to do the other configurations
    }
}

在应用程序启动时(或者你初始化背景下,第一次使用前),你必须初始化数据库。因此,你可以用它检查数据库和处理不同的初始化。内建有像DropCreateDatabaseAlways或DropCreateDatabaseIfModelChanges=>您需要创建自己刚刚忽略任何差异。在我的示例我已创建一个只抛出一个异常时,该模型不同(我想处理好与scipts进行第一次尝试模型的变化):

At the application startup (or before you initialize your context the first time) you have to initialize the database. Therefore you can use an initializer which checks the database and handles differences. Build in there are things like "DropCreateDatabaseAlways" or "DropCreateDatabaseIfModelChanges" => you would need to create your own which just ignores any differences. In my sample i have create one which just throws an exception when the model differs (i wanted to handle model changes with scipts for the first try):

//before using the context the first time i'm calling, you can ignore the connection string
DbContextInitializer.Init(conString);

public static class DbContextInitializer
{
    public static void Init (string connectionString)
    {
        Database.SetInitializer(new CreateDbThrowExceptionIfModelDiffersInitializer<SMDbContext>());

        using(var dbContenxt = new MyDbContext(connectionString))
        {
            try
            {
                dbContenxt.Database.Initialize(true);
            }
            catch(DatabaseModelDiffersException diffException)
            {
                // some magic...
            }
            catch(Exception ex)
            {
                // TODO: log
                throw;
            }
        }
    }

    public class CreateDbThrowExceptionIfModelDiffersInitializer<TContext> : IDatabaseInitializer<TContext> where TContext : DbContext
    {
        public void InitializeDatabase(TContext context)
        {
            using (new TransactionScope(TransactionScopeOption.Suppress))
            {
                if (!context.Database.Exists())
                    context.Database.Create();
            }

            if (!context.Database.CompatibleWithModel(true))
            {
                throw new DatabaseModelDiffersException("Database Model differs!");
            }
        }

        protected virtual void Seed(TContext context)
        {
            // create data if you like
        }
    }

    // just an exception i'm using for later useage
    public class DatabaseModelDiffersException : Exception
    {
        public DatabaseModelDiffersException(string msg) : base(msg)
        {}
    }
}

希望你已经得到了你的想法可以处理与实体框架动态的表名!
如果有更多问题,只是问;)

Hope you have got an idea of you can handle dynamic table names with entity framework! If there are more questions just ask ;)

这篇关于更改实体映射到另一个&QUOT;未知&QUOT;表在运行时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆