मुझे पता है कि मूल पोस्ट ईएफ के 6.1 संस्करण को संदर्भित करता है, लेकिन कुछ शोध के बाद मुझे ईएफ कोर (1.1 संस्करण) की धाराप्रवाह एपीआई में फ़िल्टर किए गए इंडेक्स के लिए एक विस्तार विधि जोड़ने का एक तरीका मिला है। शायद किसी को यह उपयोगी लगेगा (और शायद पुराने संस्करणों में इसे लागू करने का एक तरीका भी है)। मुझे आपको चेतावनी देना है हालांकि। चूंकि यह समाधान Microsoft.EntityFrameworkCore.Migrations.Internal
और Microsoft.EntityFrameworkCore.Infrastructure
नामस्थानों से कक्षाओं का उपयोग करता है, इसलिए यह गारंटी नहीं है कि ईएफ अपडेट होने के बाद यह कोड काम करेगा। वहाँ एक मालिश इन नामस्थान के भीतर प्रत्येक वर्ग का एक सारांश में शामिल करते हुए कहा कि
This API may change or be removed in future releases
है, तो आप चेतावनी दी गई है।
लेकिन बिंदु पर।
सबसे पहले आपको IndexBuilder
के लिए मानक एक्सटेंशन विधि बनाना है। इसकी मुख्य ज़िम्मेदारी निर्माण सूचकांक की स्थिति के साथ एक नई एनोटेशन जोड़ने जा रही है। एक तरफ एपीआई के साथ बाद में इस विधि का उपयोग करेगा। कृपया हमारी एनोटेशन SqlServer:FilteredIndex
पर कॉल करें।
static class FilteredIndexExtension
{
public static IndexBuilder Filtered(this IndexBuilder indexBuilder, string condition)
{
indexBuilder.HasAnnotation("SqlServer:FilteredIndex", condition);
return indexBuilder;
}
}
अगला यह व्याख्या वास्तव में माइग्रेशन के अंदर शामिल किए जाने की अनुमति देने के लिए किया है। इंडेक्स बिल्डर्स के लिए आपको SqlServerMigrationsAnnotationProvider
के डिफ़ॉल्ट व्यवहार को ओवरराइड करना होगा।
class ExtendedSqlServerMigrationsAnnotationProvider : SqlServerMigrationsAnnotationProvider
{
public override IEnumerable<IAnnotation> For(IIndex index)
{
var baseAnnotations = base.For(index);
var customAnnotatinos = index.GetAnnotations().Where(a => a.Name == "SqlServer:FilteredIndex");
return baseAnnotations.Concat(customAnnotatinos);
}
}
अब सबसे कठिन हिस्सा आता है। हमें इंडेक्स के संबंध में SqlServerMigrationsSqlGenerator
के डिफ़ॉल्ट व्यवहार को ओवरराइड करना होगा।
class ExtendedSqlServerMigrationsSqlGenerator : SqlServerMigrationsSqlGenerator
{
public ExtendedSqlServerMigrationsSqlGenerator(IRelationalCommandBuilderFactory commandBuilderFactory, ISqlGenerationHelper sqlGenerationHelper, IRelationalTypeMapper typeMapper, IRelationalAnnotationProvider annotations, IMigrationsAnnotationProvider migrationsAnnotations) : base(commandBuilderFactory, sqlGenerationHelper, typeMapper, annotations, migrationsAnnotations)
{
}
protected override void Generate(CreateIndexOperation operation, IModel model, MigrationCommandListBuilder builder, bool terminate)
{
base.Generate(operation, model, builder, false);
var filteredIndexCondition = operation.FindAnnotation("SqlServer:FilteredIndex");
if (filteredIndexCondition != null)
builder.Append($" WHERE {filteredIndexCondition.Value}");
if (terminate)
{
builder.AppendLine(SqlGenerationHelper.StatementTerminator);
EndStatement(builder);
}
}
}
आप देख सकते हैं, हम आधार जनरेटर यहाँ, बुला रहे हैं तो हमारे हालत यह बदले बिना यह के अंत में जोड़ दिया जाएगा। हमें याद रखना होगा कि यहां बेस एसक्यूएल स्टेटमेंट को समाप्त नहीं करना है (base.Generate
विधि को अंतिम तर्क false
है)। यदि हमारी एनोटेशन सेट है तो हम SQL कथन के अंत में WHERE
खंड के बाद अपना मान जोड़ सकते हैं। उसके बाद, इस विधि को पारित तर्क के आधार पर, हम आखिरकार कथन को समाप्त कर सकते हैं या इसे छोड़ सकते हैं।
काम करने के लिए उन सभी भागों के लिए हम अपने DbContext
की OnConfiguring
विधि अधिभावी द्वारा अपने नए संस्करणों के साथ पुराने सेवाओं को बदलने के लिए।
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.ReplaceService<SqlServerMigrationsAnnotationProvider, ExtendedSqlServerMigrationsAnnotationProvider>();
optionsBuilder.ReplaceService<SqlServerMigrationsSqlGenerator, ExtendedSqlServerMigrationsSqlGenerator>();
}
अब हम इस तरह हमारे विस्तार विधि का उपयोग कर सकते हैं:
builder.HasIndex(a => a.Identity).IsUnique().Filtered("[End] IS NULL");
यह इस तरह पलायन उत्पन्न करेगा:
migrationBuilder.CreateIndex(
name: "IX_Activities_Identity",
table: "Activities",
column: "Identity",
unique: true)
.Annotation("SqlServer:FilteredIndex", "[End] IS NULL");
और पैकेज प्रबंधक कंसोल में Script-Migration
commad बुला के बाद हम देखेंगे परिणामी एसक्यूएल इस प्रकार है:
CREATE UNIQUE INDEX [IX_Activities_Identity] ON [Activities] ([Identity]) WHERE [End] IS NULL;
इस विधि का उपयोग वास्तव में किसी भी कस्टम एसक्यूएल जनरेटर को ef core fluent api में शामिल करने के लिए किया जा सकता है। कम से कम जब तक ईएफ एपीआई वही रहता है।
दिलचस्प लेख: http://stackoverflow.com/questions/29922099/how-to-add-an-index-on-multiple-columns-with-asc-desc-sort-using-the-fluent-api – Elisabeth