সত্তা ফ্রেমওয়ার্কে একাধিক কলামের জন্য অনন্য কী বাধা


243

আমি প্রথমে সত্ত্বা ফ্রেমওয়ার্ক 5.0 কোড ব্যবহার করছি;

public class Entity
 {
   [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   public string EntityId { get; set;}
   public int FirstColumn  { get; set;}
   public int SecondColumn  { get; set;}
 }

আমি মিশ্রণটি এর মধ্যে FirstColumnএবং SecondColumnঅনন্য হিসাবে তৈরি করতে চাই ।

উদাহরণ:

Id  FirstColumn  SecondColumn 
1       1              1       = OK
2       2              1       = OK
3       3              3       = OK
5       3              1       = THIS OK 
4       3              3       = GRRRRR! HERE ERROR

যাইহোক এটি করতে কি আছে?

উত্তর:


368

সত্তা ফ্রেমওয়ার্ক 6.1 এর সাথে, আপনি এখন এটি করতে পারেন:

[Index("IX_FirstAndSecond", 1, IsUnique = true)]
public int FirstColumn { get; set; }

[Index("IX_FirstAndSecond", 2, IsUnique = true)]
public int SecondColumn { get; set; }

বৈশিষ্ট্যের দ্বিতীয় প্যারামিটারটি যেখানে আপনি সূচীতে কলামগুলির ক্রম নির্দিষ্ট করতে পারবেন।
আরও তথ্য: এমএসডিএন


12
এই, ডাটা টীকা জন্য :) সঠিক হয় তাহলে আপনি অনর্গল API ব্যবহার করে নিচের Niaher এর উত্তর দেখার জন্য উত্তর চান stackoverflow.com/a/25779348/2362036
tekiegirl

8
তবে বিদেশী কীগুলির জন্য এটির কাজ করা আমার দরকার! আপনি কি আমাকে সাহায্য করতে পারেন?
feedc0de

2
@ 0xFEEDC0DE নীচে আমার উত্তরটি সূচকগুলিতে বিদেশী কীগুলির ব্যবহারের ঠিকানায় দেখুন।
Kryptos

1
আপনি কীভাবে লেনক টু বর্গ বেতার এই সূচকটি ব্যবহার করবেন তা পোস্ট করতে পারেন?
ব্লুবারন

4
@ জেজেএস - আমি এটি কাজ করতে পেরেছি যেখানে সম্পত্তিগুলির মধ্যে একটি বিদেশী চাবি ছিল .. কোনও সুযোগে কী আপনার চাবিটি একটি বার্চর বা এনভারচর? একটি দৈর্ঘ্যের একটি সীমা রয়েছে যার একটি অনন্য কী হিসাবে ব্যবহার করা যেতে পারে .. stackoverflow.com/questions/2863993/…
ডেভ লরেন্স

129

আমি সমস্যাটি সমাধানের তিনটি উপায় পেয়েছি।

সত্তা ফ্রেমওয়ার্ক কোরে অনন্য সূচি:

প্রথম পদ্ধতির:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
   modelBuilder.Entity<Entity>()
   .HasIndex(p => new {p.FirstColumn , p.SecondColumn}).IsUnique();
}

বিকল্প কীগুলি ব্যবহার করে ইএফ কোরের সাথে স্বতন্ত্র সীমাবদ্ধতা তৈরির দ্বিতীয় পদ্ধতি

উদাহরণ

একটি কলাম:

modelBuilder.Entity<Blog>().HasAlternateKey(c => c.SecondColumn).HasName("IX_SingeColumn");

একাধিক কলাম:

modelBuilder.Entity<Entity>().HasAlternateKey(c => new [] {c.FirstColumn, c.SecondColumn}).HasName("IX_MultipleColumns");

EF 6 এবং নীচে:


প্রথম পদ্ধতির:

dbContext.Database.ExecuteSqlCommand(string.Format(
                        @"CREATE UNIQUE INDEX LX_{0} ON {0} ({1})", 
                                 "Entitys", "FirstColumn, SecondColumn"));

এই পদ্ধতির খুব দ্রুত এবং দরকারী কিন্তু মূল সমস্যা হ'ল সত্তা ফ্রেমওয়ার্ক এই পরিবর্তনগুলি সম্পর্কে কিছুই জানে না!


দ্বিতীয় পদ্ধতির:
আমি এই পোস্টে এটি খুঁজে পেয়েছি কিন্তু আমি নিজে চেষ্টা করেছিলাম না।

CreateIndex("Entitys", new string[2] { "FirstColumn", "SecondColumn" },
              true, "IX_Entitys");

এই পদ্ধতির সমস্যাটি নিম্নলিখিত: এটির DbMigration দরকার তাই আপনার যদি এটি না থাকে তবে আপনি কী করবেন?


তৃতীয় পদ্ধতি:
আমি মনে করি এটি সেরা one তবে এটি করতে কিছুটা সময় প্রয়োজন। আমি আপনাকে কেবল এর পিছনে ধারণাটি দেখাব: এই লিঙ্কটিতে http://code.msdn.microsoft.com/CSASPNETUniqueConstraintInE-d357224a আপনি অনন্য কী ডেটা টীকা দেওয়ার কোডটি খুঁজে পেতে পারেন:

[UniqueKey] // Unique Key 
public int FirstColumn  { get; set;}
[UniqueKey] // Unique Key 
public int SecondColumn  { get; set;}

// The problem hier
1, 1  = OK 
1 ,2  = NO OK 1 IS UNIQUE

এই পদ্ধতির জন্য সমস্যা; আমি কীভাবে তাদের একত্রিত করতে পারি? উদাহরণস্বরূপ এই মাইক্রোসফ্ট বাস্তবায়নটি বাড়ানোর আমার ধারণা আছে:

[UniqueKey, 1] // Unique Key 
public int FirstColumn  { get; set;}
[UniqueKey ,1] // Unique Key 
public int SecondColumn  { get; set;}

পরে মাইক্রোসফ্ট উদাহরণে বর্ণিত আইডিটাবেসআইনিটিয়ালাইজারে আপনি প্রদত্ত পূর্ণসংখ্যা অনুযায়ী কীগুলি একত্রিত করতে পারেন। তবে একটি বিষয় অবশ্যই লক্ষণীয়: যদি অনন্য সম্পত্তিটি টাইপ স্ট্রিংয়ের হয় তবে আপনাকে ম্যাক্সেলেন্থ সেট করতে হবে।


1
(y) আমি এই উত্তরটি আরও ভাল পাই। আরেকটি বিষয়, তৃতীয় পদ্ধতির অগত্যা সেরা নাও হতে পারে। (আমি আসলে প্রথমটি পছন্দ করি)) আমি ব্যক্তিগতভাবে আমার সত্ত্বার ক্লাসে কোনও ইএফ শিল্পকর্ম না নিয়ে পছন্দ করি।
নাজিব

1
সম্ভবত, দ্বিতীয় পদ্ধতির হওয়া উচিত: CREATE UNIQUE INDEX ix_{1}_{2} ON {0} ({1}, {2})? ( বিএল দেখুন )
এ কে

2
বোকা প্রশ্ন: কেন আপনি "আইএক্স_" দিয়ে আপনার সমস্ত নাম শুরু করবেন?
বাসটিয়েন ভান্ডামমে

1
পছন্দ করুন ইএফ দ্বারা অটো উত্পন্ন সূচক IX_ দিয়ে শুরু হয়। এটি ডিফল্টরূপে ইএফ সূচকে একটি সম্মেলন বলে মনে হচ্ছে, সূচকের নাম হবে IX_ {সম্পত্তির নাম}}
বাসাম আলুগিলি

1
হ্যাঁ তা হওয়া উচিত। সাবলীল এপিআই প্রয়োগের জন্য ধন্যবাদ।
জেএসওএন

75

আপনি যদি কোড-ফার্স্ট ব্যবহার করছেন তবে আপনি একটি কাস্টম এক্সটেনশান HasUniqueIndexAnnotation প্রয়োগ করতে পারেন

using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Infrastructure.Annotations;
using System.Data.Entity.ModelConfiguration.Configuration;

internal static class TypeConfigurationExtensions
{
    public static PrimitivePropertyConfiguration HasUniqueIndexAnnotation(
        this PrimitivePropertyConfiguration property, 
        string indexName,
        int columnOrder)
    {
        var indexAttribute = new IndexAttribute(indexName, columnOrder) { IsUnique = true };
        var indexAnnotation = new IndexAnnotation(indexAttribute);

        return property.HasColumnAnnotation(IndexAnnotation.AnnotationName, indexAnnotation);
    }
}

তারপরে এটির মতো ব্যবহার করুন:

this.Property(t => t.Email)
    .HasColumnName("Email")
    .HasMaxLength(250)
    .IsRequired()
    .HasUniqueIndexAnnotation("UQ_User_EmailPerApplication", 0);

this.Property(t => t.ApplicationId)
    .HasColumnName("ApplicationId")
    .HasUniqueIndexAnnotation("UQ_User_EmailPerApplication", 1);

যার ফলে এই মাইগ্রেশন হবে:

public override void Up()
{
    CreateIndex("dbo.User", new[] { "Email", "ApplicationId" }, unique: true, name: "UQ_User_EmailPerApplication");
}

public override void Down()
{
    DropIndex("dbo.User", "UQ_User_EmailPerApplication");
}

এবং শেষ পর্যন্ত ডাটাবেস হিসাবে শেষ:

CREATE UNIQUE NONCLUSTERED INDEX [UQ_User_EmailPerApplication] ON [dbo].[User]
(
    [Email] ASC,
    [ApplicationId] ASC
)

3
তবে তা সূচক বাধা নয়!
রোমান পোক্রভস্কিজ

3
আপনার দ্বিতীয় কোড ব্লকে ( this.Property(t => t.Email)), এতে রয়েছে শ্রেণিটি কী? (যেমন: কী this)
জোব্রোকহাউস

2
nvm। EntityTypeConfiguration<T>
জোব্রোকহাউস

5
@ রোমানপোক্রোভস্কিজ: একটি অনন্য সূচক এবং একটি অনন্য বাধার মধ্যে পার্থক্যটি এসকিউএল সার্ভারে এর রেকর্ডগুলি কীভাবে বজায় রাখা হয় তা একটি বিষয় হিসাবে উপস্থিত হয়। বিশদর জন্য টেকনিক.মাইক্রোসফট.ইন.ইউএস / লিবারিয়ান/aa224827%28v=sql.80%29.aspx দেখুন ।
ম্যাস ডট নেট

1
@ নায়াহার আমি আপনার দুর্দান্ত বর্ধন পদ্ধতির প্রশংসা করি
মোহসেন আফশিন

18

আপনার একটি যৌগিক কী সংজ্ঞায়িত করতে হবে।

ডেটা টীকাগুলি সহ এটি দেখতে এরকম দেখাচ্ছে:

public class Entity
 {
   public string EntityId { get; set;}
   [Key]
   [Column(Order=0)]
   public int FirstColumn  { get; set;}
   [Key]
   [Column(Order=1)]
   public int SecondColumn  { get; set;}
 }

অনমোডেল ক্রিয়েটিংকে ওভাররাইড করার সময় আপনি নির্দিষ্ট করে উল্লেখ করতে পারেন:

modelBuilder.Entity<Entity>().HasKey(x => new { x.FirstColumn, x.SecondColumn });

2
তবে কীগুলি কী নয় আমি কেবল তাদের চাই অনন্য হিসাবে কীটি আইডি হওয়া উচিত? সাহায্যের জন্য আমি অনুসন্ধানটি আপডেট করেছি!
বাসাম আলুগিলি

16

নায়াহারের উত্তর উল্লেখ করে বলা হয়েছে যে সাবলীল এপিআই ব্যবহার করতে আপনার একটি কাস্টম এক্সটেনশন প্রয়োজন লেখার সময় সঠিক হতে পারে। আপনি এখন (ইএফ কোর ২.১) নিম্নরূপ সাবলীল এপিআই ব্যবহার করতে পারেন:

modelBuilder.Entity<ClassName>()
            .HasIndex(a => new { a.Column1, a.Column2}).IsUnique();

9

বিদেশী কী সহ যৌগিক সূচকগুলি ব্যবহারের জন্য @ চক উত্তর সম্পূর্ণ করা ।

আপনাকে এমন একটি সম্পত্তি নির্ধারণ করতে হবে যা বিদেশী কীটির মান ধরে রাখতে পারে। তারপরে আপনি এই সম্পত্তিটি সূচী সংজ্ঞাতে ব্যবহার করতে পারেন।

উদাহরণস্বরূপ, আমাদের কর্মচারীদের সাথে সংস্থা রয়েছে এবং যে কোনও কর্মচারীর জন্য আমাদের কেবল (নাম, সংস্থা) অনন্য প্রতিবন্ধকতা রয়েছে:

class Company
{
    public Guid Id { get; set; }
}

class Employee
{
    public Guid Id { get; set; }
    [Required]
    public String Name { get; set; }
    public Company Company  { get; set; }
    [Required]
    public Guid CompanyId { get; set; }
}

এখন কর্মী শ্রেণীর ম্যাপিং:

class EmployeeMap : EntityTypeConfiguration<Employee>
{
    public EmployeeMap ()
    {
        ToTable("Employee");

        Property(p => p.Id)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

        Property(p => p.Name)
            .HasUniqueIndexAnnotation("UK_Employee_Name_Company", 0);
        Property(p => p.CompanyId )
            .HasUniqueIndexAnnotation("UK_Employee_Name_Company", 1);
        HasRequired(p => p.Company)
            .WithMany()
            .HasForeignKey(p => p.CompanyId)
            .WillCascadeOnDelete(false);
    }
}

নোট করুন যে আমি অনন্য সূচক টীকাতে @ নীহার এক্সটেনশনও ব্যবহার করেছি।


1
এই উদাহরণে আপনার সংস্থা এবং সংস্থাআইডি উভয়ই রয়েছে। এর অর্থ হ'ল কলার অন্যটি নয় বরং একটি পরিবর্তন করতে পারে এবং ভুল ডেটা সহ একটি সত্তা রাখতে পারে।
লসম্যানোস

1
@ লসমনোস আপনি কোন কলারের কথা বলছেন? ক্লাসটি একটি ডাটাবেসে ডেটা উপস্থাপন করে। প্রশ্নের মাধ্যমে মান পরিবর্তন করা ধারাবাহিকতা নিশ্চিত করবে। ক্লায়েন্ট অ্যাপ্লিকেশন কী করতে পারে তার উপর নির্ভর করে আপনার চেকগুলি প্রয়োগ করতে পারে তবে এটি অপের সুযোগ নয়।
Kryptos

4

@ চকের গৃহীত উত্তরে একটি মন্তব্য রয়েছে যা এফকে-র ক্ষেত্রে কাজ করবে না।

এটি আমার জন্য কাজ করেছে, EF6 এর ক্ষেত্রে। নেট ৪..7.২

public class OnCallDay
{
     public int Id { get; set; }
    //[Key]
    [Index("IX_OnCallDateEmployee", 1, IsUnique = true)]
    public DateTime Date { get; set; }
    [ForeignKey("Employee")]
    [Index("IX_OnCallDateEmployee", 2, IsUnique = true)]
    public string EmployeeId { get; set; }
    public virtual ApplicationUser Employee{ get; set; }
}

অনেকক্ষণ. যাক, এটা অনেক আগে কাজ হয়েছে! আপডেটের জন্য আপনাকে ধন্যবাদ @ উত্তর উত্তর একটি মন্তব্য যোগ করুন। আমার মনে হয় চাক অনেক দিন আগে এসও ব্যবহার করে না।
বাসাম আলুগিলি

কর্মচারী সম্পত্তি কী এখানে কোনও সূচকযুক্ত হওয়ার জন্য তার দৈর্ঘ্য সীমাবদ্ধ করার জন্য একটি বৈশিষ্ট্যের প্রয়োজন? অন্যটি এর ভিআচআরএআরএআরএক্স (ম্যাক্স) দিয়ে তৈরি যার কোন সূচক থাকতে পারে না? কর্মচারীদের সাথে [স্ট্রিংলেন্ট (255)] যোগ করুন
লর্ড দার্থ ভাদার

কর্মচারী একজন জিআইডি। অনেক টিউটোরিয়াল
গাইডের

3

আমি ধরে নিয়েছি আপনি সর্বদা EntityIdপ্রাথমিক কী হতে চান , সুতরাং এটি একটি সংমিশ্রিত কী দ্বারা প্রতিস্থাপন করা কোনও বিকল্প নয় (কেবলমাত্র যদি যৌগিক কীগুলির সাথে কাজ করা আরও জটিল এবং কারণ এটিতে মূল কী রয়েছে তবে এটি খুব বুদ্ধিমান নয় ব্যবসার যুক্তিতে)

আপনার যা করা উচিত তা হ'ল ডাটাবেসের উভয় ক্ষেত্রেই একটি অনন্য কী তৈরি করা এবং পরিবর্তনগুলি সংরক্ষণের সময় বিশেষত অনন্য কী লঙ্ঘনের ব্যতিক্রমগুলি অনুসন্ধান করা।

অতিরিক্ত পরিবর্তনগুলি সংরক্ষণের আগে আপনি অনন্য মূল্যবোধ পরীক্ষা করতে পারেন (হওয়া উচিত)। এটি করার সর্বোত্তম উপায় হল একটি Any()ক্যোয়ারী, কারণ এটি স্থানান্তরিত ডেটার পরিমাণ হ্রাস করে:

if (context.Entities.Any(e => e.FirstColumn == value1 
                           && e.SecondColumn == value2))
{
    // deal with duplicate values here.
}

সাবধান থাকুন যে এই চেকটি কখনওই যথেষ্ট নয়। চেক এবং আসল প্রতিশ্রুতিবদ্ধতার মধ্যে সর্বদা কিছুটা বিলম্ব থাকে তাই আপনার সর্বদা অনন্য বাধা + ব্যতিক্রম হ্যান্ডলিংয়ের প্রয়োজন হবে।


3
উত্তরের জন্য @ গার্টআরনল্ড ধন্যবাদ তবে আমি ব্যবসায়ের স্তরের স্বতন্ত্রতাটি বৈধতা দিতে চাই না এটি একটি ডাটাবেস কাজ এবং এটি ডাটাবেসে করা হবে!
বাসাম আলুগিলি

2
ঠিক আছে, তারপরে অনন্য সূচীতে আটকে দিন। তবে আপনাকে কোনওভাবেই ব্যবসায় স্তরতে সূচক লঙ্ঘনের মোকাবেলা করতে হবে।
গার্ট আর্নল্ড

1
বাইরে থেকে যখন আমি এই ধরণের ব্যতিক্রম পাই তখন আমি ক্যাচ করব এবং সম্ভবত ত্রুটিটি রিপোর্ট করে প্রক্রিয়াটি ভেঙে দেব বা অ্যাপ্লিকেশনটি বন্ধ করে দেব।
বাসাম আলুগিলি

3
হ্যাঁ, ... আমাকে কি তাতে সাড়া দেওয়ার দরকার আছে? মনে রাখবেন আমি আপনার আবেদনের কিছুই জানেন, আমি তোমাকে বলতে পারবো না কি সবচেয়ে ভালো উপায় এই ব্যতিক্রম সঙ্গে মোকাবিলা করার জন্য, শুধুমাত্র যে আপনি তাদের সঙ্গে মোকাবেলা করতে হবে।
গার্ট আর্নল্ড

2
EF এর সাথে ডিবি অনন্য সীমাবদ্ধতা সম্পর্কে সতর্ক থাকুন। আপনি যদি এটি করেন এবং তারপরে আপনি এমন কোনও আপডেট পেয়ে শেষ করেন যা অনন্য কীটির অংশ থাকা কলামগুলির একটির মানকে ফ্লিপ-ফ্লপ করে দেয় তবে আপনি একটি সম্পূর্ণ লেনদেন স্তর যোগ না করলে সত্তা ফ্রেমওকার সেভ এ ব্যর্থ হবে। উদাহরণস্বরূপ: পৃষ্ঠা অবজেক্টে উপাদানগুলির একটি শিশু সংগ্রহ রয়েছে। প্রতিটি উপাদান এর SortOrder আছে। আপনি পেজআইডি এবং সোর্টারর্ডারের কম্বো অনন্য হতে চান। সামনের প্রান্তে, ব্যবহারকারী 1 এবং 2 এর সাথে সাজানো বাছাই করা উপাদানগুলির ক্রমগুলি ফ্লপ করুন Ent সত্তা ফ্রেমওয়ার্ক এটি একবারে সর্ডারর্ডার আপডেট করার চেষ্টা করছে সেভ বি / সি ব্যর্থ করবে।
ইজিপি 3'14

1

'ছক' প্রস্তাবিত পদ্ধতির সাহায্যে সম্প্রতি 2 টি কলামের স্বতন্ত্রতার সাথে একটি যৌগিক কী যুক্ত করেছেন, ধন্যবাদ @ চক। কেবলমাত্র এই কাছেই আমার কাছে পরিষ্কার দেখা গেছে:

public int groupId {get; set;}

[Index("IX_ClientGrouping", 1, IsUnique = true)]
public int ClientId { get; set; }

[Index("IX_ClientGrouping", 2, IsUnique = true)]
public int GroupName { get; set; }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.