c# entity framework - متعدد المستأجر مع الرمز الأول EF6





2 Answers

نهج لطيف للغاية وساعدني في الحصول على حل أكثر مباشرة إلى الأمام. يمكنك تجاوز اسم الأسلوب فقط ، يتم استخدامه في كل كاتب .... عذرا على إجابة جديدة ، ولكن لا يسمح لي بالتعليق ....

public class SqlServerSchemaAwareMigrationSqlGenerator:SqlServerMigrationSqlGenerator
{

    private string _schema;

    public accountMigrationSqlGenerator(string schema)
    {
        _schema = schema;
    }

    protected override string Name(string name)
    {

        int p = name.IndexOf('.');
        if(p>0)
        {
            name = name.Substring(p + 1);
        }

        return $"[{_schema}].[{name}]";

    }

}
crud operation in

تحتاج منظمتنا إلى قاعدة بيانات واحدة ، متعددة المستأجرين
(من خلال مخطط الجدول ، وليس حسب معرف المستأجر ).

هناك مقالة رائعة هنا للبدء في هذا النوع من الأشياء هنا: http://romiller.com/2011/05/23/ef-4-1-multi-tenant-with-code-first/

في منتصف المقال ، هذا مكتوب:

ستلاحظ (ربما مع بعض الفزع) نحتاج إلى كتابة التعليمات البرمجية لتكوين مخطط الجدول لكل كيان. من المسلم به أنه لا يوجد الكثير من الأحبار السحرية التي ترعى هذا الرمز ... في الإصدارات المستقبلية من EF ، سنكون قادرين على استبدال ذلك باتفاقية مخصصة أكثر نظافة.

يتمثل هدفنا في الحصول على أنظف طريقة ممكنة للحصول على فئة سياق واحدة يمكننا استخدامها للاتصال بمخططات متعددة لها نفس الطراز.
( لاحظ أن modelBuilder.HasDefaultSchema لا يبدو كافيا ، لأنه لا ينطبق إلا في المرة الأولى التي يهيئ فيها EF السياق ويدير OnModelCreating)

هل توجد الاتفاقية المخصصة الأنظف المذكورة أعلاه في EF5 أو EF6؟
أم أن هناك طريقة أنظف للتعامل مع هذا بطريقة ما؟

ملاحظة: لقد طرحت هذا السؤال أيضًا على منتدى التطوير ، حيث يبدو أنه يتعلق أكثر باتجاه EF ، لكنه أراد أن يرى ما إذا كان لدى أي شخص هنا بدائل.

ملاحظة 2: لست قلقاً بشأن عمليات الترحيل ، سنقوم بمعالجة ذلك بشكل منفصل.




شكرا ل: ! أنت تدّخرني لسنوات

التعديل الخاص بي لـ Oracle DB تحت EF 6:

public class IntegrationDbContext : DbContext, IDbModelCacheKeyProvider
{
    private static readonly ILog __log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

    /// <summary>
    /// Factory method
    /// </summary>
    public static IntegrationDbContext Create(string connectionStringName)
    {
        return new IntegrationDbContext(connectionStringName, GetDBSchema(connectionStringName));
    }

    /// <summary>
    /// Constructor
    /// </summary>
    public IntegrationDbContext()
    {
        Database.SetInitializer<IntegrationDbContext>(null);
    }

    /// <summary>
    /// Constructor
    /// </summary>
    internal IntegrationDbContext(string connectionString, string schemaName)
        : base("name={0}".Fill(connectionString))
    {
        Database.SetInitializer<IntegrationDbContext>(null);
        SchemaName = schemaName;
    }

    /// <summary>
    /// DB schema name
    /// </summary>
    public string SchemaName { get; private set; }

    #region Tables
    /// <summary>
    /// Integration table "SYNC_BONUS_DISTRIBUTION"
    /// </summary>
    public virtual DbSet<SYNC_BONUS_DISTRIBUTION> SYNC_BONUS_DISTRIBUTION { get; set; }

    /// <summary>
    /// Integration table "SYNC_MESSAGE_DISTRIBUTION"
    /// </summary>
    public virtual DbSet<SYNC_MESSAGE_DISTRIBUTION> SYNC_MESSAGE_DISTRIBUTION { get; set; }

    /// <summary>
    /// Integration table "IMPORT_TEMPLATES"
    /// </summary>
    public virtual DbSet<IMPORT_TEMPLATE> IMPORT_TEMPLATES { get; set; }

    #endregion //Tables

    private static Dictionary<string, string> __schemaCache = new Dictionary<string, string>();
    private static object __schCacheLock = new object();
    /// <summary>
    /// Gets DB schema name from connection string, or default from config
    /// </summary>
    private static string GetDBSchema(string connectionStringName)
    {
        string result;
        if (!__schemaCache.TryGetValue(connectionStringName, out result))
        {
            lock (__schCacheLock)
            {
                if (!__schemaCache.TryGetValue(connectionStringName, out result))
                {
                    DbConnectionStringBuilder builder = new DbConnectionStringBuilder();
                    builder.ConnectionString = ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;
                    result = builder.ContainsKey("User ID") ? builder["User ID"] as string : ConfigurationManager.AppSettings["DefaultIntegrationSchema"];
                    __schemaCache.Add(connectionStringName, result);
                }
            }
        }
        return result;
    }

    /// <summary>
    /// Context initialization
    /// </summary>
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        __log.DebugFormat("OnModelCreating for integration model in schema: {0}", SchemaName);
        if (SchemaName != null)
        {
            modelBuilder.HasDefaultSchema(SchemaName);
        }
        //### CLOB settings
        modelBuilder.Properties().Where(p => p.PropertyType == typeof(string) &&
                                             p.GetCustomAttributes(typeof(MaxLengthAttribute), false).Length == 0)
                                                .Configure(p => p.HasMaxLength(2000));

        base.OnModelCreating(modelBuilder);
    }

    /// <summary>
    /// Implementation of <see cref="IDbModelCacheKeyProvider.CacheKey"/> - thanks by this is 'OnModelCreating' calling for each specific schema.
    /// </summary>
    public string CacheKey
    {
        get { return SchemaName; }
    }
}





Related