EF কোডে দশমিক নির্ভুলতা এবং স্কেল প্রথম


230

আমি এই কোড-প্রথম পদ্ধতির সাথে পরীক্ষা করছি, তবে আমি এখন জানতে পারি যে টাইপ সিস্টেমের একটি সম্পত্তি ec

আমি কীভাবে ডাটাবেস কলামের যথার্থতা সেট করব?


11
একটি উপায় হ'ল [Column(TypeName = "decimal(18,4)")]আপনার দশমিক বৈশিষ্ট্যের জন্য অ্যাট্রিবিউটটি ব্যবহার করা
এস.স্পার্পোশন

[কলাম (টাইপনাম = "দশমিক (18,4)")] দুর্দান্ত কাজ করেছে !!!
ব্রায়ান রাইস

উত্তর:


257

ডেভ ভ্যান ডেন এয়েণ্ডের উত্তর এখন পুরানো। 2 টি গুরুত্বপূর্ণ পরিবর্তন রয়েছে, ইএফ 4.1 থেকে মডেলবিল্ডার শ্রেণি এখন ডিবিমোডেলবিল্ডার এবং এখন একটি ডেসিমালপ্রপার্টি কনফিগারেশন রয়েছে .হ্যাসপ্রেসিশন পদ্ধতি যার স্বাক্ষর রয়েছে:

public DecimalPropertyConfiguration HasPrecision(
byte precision,
byte scale )

যেখানে দশমিক বিন্দু পড়ে এবং স্কেল যে পরিমাণে এটি সংরক্ষণ করবে তার সংখ্যা নির্বিশেষে যেখানে স্পষ্টতা হ'ল ডিবি সংরক্ষণ করবে সেই সংখ্যাগুলির মোট সংখ্যা।

সুতরাং দেখানো হিসাবে বৈশিষ্ট্যগুলির মাধ্যমে পুনরাবৃত্তি করার প্রয়োজন নেই তবে কেবল এখান থেকে কল করা যেতে পারে

public class EFDbContext : DbContext
{
   protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
   {
       modelBuilder.Entity<Class>().Property(object => object.property).HasPrecision(12, 10);

       base.OnModelCreating(modelBuilder);
   }
}

ডিবিমোডেলবিল্ডারের সাথে যে কেউ সমস্যা নিয়ে আসছেন, তার জন্য চেষ্টা করুনSystem.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder
লয়েড পাওয়েল

1
আমি খেয়াল করেছি আপনি কখনও ডাকেন নি base.OnModelCreating(modelBuilder);। আইডিইয়ের পরিবর্তে সে ইচ্ছাকৃত বা কেবল অনলাইনে কোড টাইপিংয়ের শিকার ছিল?
বেনসওয়েেন

1
@ স্পেনের জন্য বেনসওয়ে ধন্যবাদ, এটি আমার বাদ, ইচ্ছাকৃত কিছু নয়। আমি উত্তরটি সম্পাদনা করব।
আলেক্সসি

26
হাসপ্রেসিজনে 2 টি যুক্তি (যথার্থতা, স্কেল) খারাপভাবে নথিভুক্ত করা হয়েছে। দশমিক বিন্দু যেখানেই পড়ে তা নির্বিশেষে নির্ভুলতা হ'ল এটি সংখ্যার মোট সংখ্যাটি সংরক্ষণ করবে। স্কেল হল দশমিক জায়গাগুলির সংখ্যা যা এটি সঞ্চয় করবে।
ক্রিস মোসচিনি 21

1
কোনও স্থানে সমস্ত সত্তার দশমিক বৈশিষ্ট্যের জন্য এটি সেট করার জন্য কি কোনও EF কনফিগারেশন রয়েছে? আমরা সাধারণত (19,4) ব্যবহার করি। এটি সমস্ত দশমিক বৈশিষ্ট্যের সাথে স্বয়ংক্রিয়ভাবে প্রয়োগ করা ভাল লাগবে, সুতরাং আমরা কোনও সম্পত্তি যথার্থতা সেট করতে এবং গণনাগুলিতে প্রত্যাশিত নির্ভুলতা মিস করতে ভুলে যেতে পারি না।
মাইক ডি ক্লার্ক

89

আপনি যদি decimalsEF6- এ সবার জন্য নির্ভুলতা নির্ধারণ করতে চান তবে আপনি DecimalPropertyConventionব্যবহৃত ডিফল্ট কনভেনশনটি প্রতিস্থাপন করতে পারেন DbModelBuilder:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Conventions.Remove<DecimalPropertyConvention>();
    modelBuilder.Conventions.Add(new DecimalPropertyConvention(38, 18));
}

DecimalPropertyConventionEF6 এ ডিফল্ট কলামগুলিতে decimalবৈশিষ্ট্য মানচিত্র decimal(18,2)

আপনি যদি কেবল পৃথক বৈশিষ্ট্যগুলির নির্দিষ্ট নির্দিষ্টতা রাখতে চান তবে সত্তার সম্পত্তির জন্য যথাযথতাটি এখানে সেট করতে পারেন DbModelBuilder:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<MyEntity>().Property(e => e.Value).HasPrecision(38, 18);
}

বা, EntityTypeConfiguration<>সত্তার জন্য একটি যুক্ত করুন যা স্পষ্টতা নির্দিষ্ট করে:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Configurations.Add(new MyEntityConfiguration());
}

internal class MyEntityConfiguration : EntityTypeConfiguration<MyEntity>
{
    internal MyEntityConfiguration()
    {
        this.Property(e => e.Value).HasPrecision(38, 18);
    }
}

1
আমার প্রিয় সমাধান। কোডফার্স্ট এবং মাইগ্রেশন ব্যবহার করার সময় নিখুঁত কাজ করে: EF সমস্ত শ্রেণীর সমস্ত বৈশিষ্ট্যের সন্ধান করে যেখানে "দশমিক" ব্যবহৃত হয় এবং এই বৈশিষ্ট্যগুলির জন্য একটি স্থানান্তর উত্পন্ন করে। গ্রেট!
Okieh

75

আমি এর জন্য একটি কাস্টম অ্যাট্রিবিউট তৈরি করতে বেশ ভাল সময় কাটিয়েছি:

[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
public sealed class DecimalPrecisionAttribute : Attribute
{
    public DecimalPrecisionAttribute(byte precision, byte scale)
    {
        Precision = precision;
        Scale = scale;

    }

    public byte Precision { get; set; }
    public byte Scale { get; set; }

}

এটি এটি ব্যবহার করে

[DecimalPrecision(20,10)]
public Nullable<decimal> DeliveryPrice { get; set; }

এবং যাদুটি কিছু প্রতিবিম্ব সহ মডেল তৈরিতে ঘটে

protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
{
    foreach (Type classType in from t in Assembly.GetAssembly(typeof(DecimalPrecisionAttribute)).GetTypes()
                                   where t.IsClass && t.Namespace == "YOURMODELNAMESPACE"
                                   select t)
     {
         foreach (var propAttr in classType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.GetCustomAttribute<DecimalPrecisionAttribute>() != null).Select(
                p => new { prop = p, attr = p.GetCustomAttribute<DecimalPrecisionAttribute>(true) }))
         {

             var entityConfig = modelBuilder.GetType().GetMethod("Entity").MakeGenericMethod(classType).Invoke(modelBuilder, null);
             ParameterExpression param = ParameterExpression.Parameter(classType, "c");
             Expression property = Expression.Property(param, propAttr.prop.Name);
             LambdaExpression lambdaExpression = Expression.Lambda(property, true,
                                                                      new ParameterExpression[]
                                                                          {param});
             DecimalPropertyConfiguration decimalConfig;
             if (propAttr.prop.PropertyType.IsGenericType && propAttr.prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
             {
                 MethodInfo methodInfo = entityConfig.GetType().GetMethods().Where(p => p.Name == "Property").ToList()[7];
                 decimalConfig = methodInfo.Invoke(entityConfig, new[] { lambdaExpression }) as DecimalPropertyConfiguration;
             }
             else
             {
                 MethodInfo methodInfo = entityConfig.GetType().GetMethods().Where(p => p.Name == "Property").ToList()[6];
                 decimalConfig = methodInfo.Invoke(entityConfig, new[] { lambdaExpression }) as DecimalPropertyConfiguration;
             }

             decimalConfig.HasPrecision(propAttr.attr.Precision, propAttr.attr.Scale);
        }
    }
}

প্রথম অংশটি হ'ল মডেলটিতে সমস্ত ক্লাস পাওয়া (আমার কাস্টম বৈশিষ্ট্যটি সেই সমাবেশে সংজ্ঞায়িত করা হয়েছে তাই আমি মডেলটি দিয়ে সমাবেশটি পেতে এটি ব্যবহার করেছি)

দ্বিতীয় পূর্বাভাসটি সেই শ্রেণীর সমস্ত বৈশিষ্ট্য কাস্টম বৈশিষ্ট্যের সাথে পায় এবং বৈশিষ্ট্যটি নিজেই তাই আমি নির্ভুলতা এবং স্কেল ডেটা পেতে পারি

তার পরে আমাকে ফোন করতে হবে

modelBuilder.Entity<MODEL_CLASS>().Property(c=> c.PROPERTY_NAME).HasPrecision(PRECISION,SCALE);

তাই আমি মডেলবিল্ডারকে ডাকি nt

এর পরে, দশমিকটি যদি নল হয় তবে আমি কল করি

Property(Expression<Func<TStructuralType, decimal?>> propertyExpression) 

পদ্ধতি (আমি অ্যারেতে অবস্থান করে এটি কল করি, এটি আমি জানি না আদর্শ, কোনও সাহায্যের অনেক প্রশংসা করা হবে)

এবং যদি এটি অগ্রহণযোগ্য না হয় আমি কল করি

Property(Expression<Func<TStructuralType, decimal>> propertyExpression)

পদ্ধতি।

ডেসিমালপ্রপার্টি কনফিগারেশন থাকার পরে আমি হাসপ্রেসিশন পদ্ধতিটি কল করি।


3
এর জন্য ধন্যবাদ. এটি হাজার হাজার ল্যাম্বডা এক্সপ্রেশন তৈরি থেকে আমাকে বাঁচিয়েছে।
শান

1
এটি দুর্দান্ত কাজ করে, এবং সুপার ক্লিন! EF 5 এর জন্য, আমি System.Data.Entity.ModelConfigration.ModelBuilder to System.Data.Entity.DbModelBuilder
কলিন

3
আমি MethodInfo methodInfo = entityConfig.GetType().GetMethod("Property", new[] { lambdaExpression.GetType() });সঠিক ওভারলোড পেতে ব্যবহার করি এখন পর্যন্ত কাজ মনে হচ্ছে।
fscan

3
আমি এটি একটি লাইব্রেরিতে গুটিয়ে রেখেছি এবং ডিবি কনটেক্সট থেকে কল করা সহজ করে দিয়েছি: github.com/richardlawley/EntityFrameworkAttributeConfig ( nuget এর মাধ্যমেও উপলভ্য)
রিচার্ড

রিচার্ড, আমি আপনার প্রকল্পের ধারণাটি পছন্দ করি তবে এটি সম্পর্কে এমন কোনও কিছুর দরকার আছে যার জন্য EF6 দরকার? কোনও EF5- সামঞ্জস্যপূর্ণ সংস্করণ থাকলে আমি এটি ব্যবহার করব, যাতে আমি আমার ODP.NET সংস্করণটি ব্যবহার করতে পারি।
প্যাট্রিক জাজালাপস্কি

50

DecimalPrecisonAttributeকিনস্লেয়ারুওয়াই থেকে ব্যবহার করে , EF6 এ আপনি এমন একটি কনভেনশন তৈরি করতে পারবেন যা বৈশিষ্ট্যযুক্ত স্বতন্ত্র বৈশিষ্ট্যগুলি পরিচালনা করবে ( সমস্ত উত্তর দশমিক বৈশিষ্ট্যগুলিকে প্রভাবিত করবে এমন উত্তরেরDecimalPropertyConvention মত উত্তর নির্ধারণের বিপরীতে) handle

[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
public sealed class DecimalPrecisionAttribute : Attribute
{
    public DecimalPrecisionAttribute(byte precision, byte scale)
    {
        Precision = precision;
        Scale = scale;
    }
    public byte Precision { get; set; }
    public byte Scale { get; set; }
}

public class DecimalPrecisionAttributeConvention
    : PrimitivePropertyAttributeConfigurationConvention<DecimalPrecisionAttribute>
{
    public override void Apply(ConventionPrimitivePropertyConfiguration configuration, DecimalPrecisionAttribute attribute)
    {
        if (attribute.Precision < 1 || attribute.Precision > 38)
        {
            throw new InvalidOperationException("Precision must be between 1 and 38.");
        }

        if (attribute.Scale > attribute.Precision)
        {
            throw new InvalidOperationException("Scale must be between 0 and the Precision value.");
        }

        configuration.HasPrecision(attribute.Precision, attribute.Scale);
    }
}

তারপরে আপনার DbContext:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Conventions.Add(new DecimalPrecisionAttributeConvention());
}

@ মিশেলএডেনফিল্ড আসলে ইএফ 6 এগুলির একটিও নেই। আমি কেন দুটি উত্তর যুক্ত করেছি, এটি একটি এবং অন্যটি আপনি উল্লেখ করেছেন। এটি এমন একটি বৈশিষ্ট্য যা আপনি মডেলের সমস্ত দশমিক বৈশিষ্ট্যকে প্রভাবিত করার পরিবর্তে একক দশমিক সম্পত্তিতে রাখতে পারেন।
kjbartel

আমার খারাপ, আপনি দুটি লিখেছেন তা খেয়াল করেননি:
Michael

1
আপনি যদি বাউন্ডস-চেক করতে যাচ্ছেন Precision, তবে আমি উপরের বাউন্ডে 28 তে সেট করার পরামর্শ দিচ্ছি (সুতরাং > 28আপনার অবস্থার মধ্যে)। এমএসডিএন ডকুমেন্টেশন অনুসারে, System.Decimalসর্বাধিক ২৮-২৯ সংখ্যক নির্ভুলতার ( এমএসডিএন.মাইক্রোসফটকম /en-us/library/364x0z75.aspx ) উপস্থাপন করতে পারে। এছাড়াও, বৈশিষ্ট্যটি Scaleহিসাবে ঘোষণা করে byte, যার অর্থ আপনার পূর্বশর্ত attribute.Scale < 0অপ্রয়োজনীয়।
নাথানএলডেনএসআর

2
@kjbartel এটি সত্য যে কিছু ডেটাবেস সরবরাহকারী 28 টিরও বেশি বড় স্পষ্টতাকে সমর্থন করে; তবে এমএসডিএন অনুসারে তা System.Decimalহয় না। সুতরাং এটি 28 এর চেয়ে বড় কোনও কিছুর উপরের সীমাবদ্ধ শর্তটি সেট করার কোনও মানে হয় না; System.Decimalস্পষ্টতই, বৃহত্তর সংখ্যাটি উপস্থাপন করতে পারে না। এছাড়াও, সচেতন হন যে এই বৈশিষ্ট্যটি এসকিউএল সার্ভার ব্যতীত ডেটা সরবরাহকারীদের জন্য দরকারী। উদাহরণস্বরূপ, পোস্টগ্রেএসকিউএল এর numericধরণটি 131072 ডিজিট পর্যন্ত নির্ভুলতার সমর্থন করে।
নাথানএলডেনএসআর

1
@ নাথানএলডেনএসআর আমি যেমন বলেছি, ডাটাবেসগুলি একটি নির্দিষ্ট পয়েন্ট দশমিক ( এমএসডিএন ) ব্যবহার করে যেখানে সিস্টেম.ডিসিমাল ভাসমান পয়েন্ট । এগুলি সম্পূর্ণ আলাদা। উদাহরণস্বরূপ decimal(38,9)কলাম থাকা সুখী রাখবে System.Decimal.MaxValueতবে decimal(28,9)কলামটি তা করবে না। স্পষ্টতাটি কেবলমাত্র 28
kjbartel

47

স্পষ্টতই, আপনি DbContext.OnModelCreating () পদ্ধতিটি ওভাররাইড করতে পারেন এবং যথার্থভাবে এটি কনফিগার করতে পারেন:

protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Product>().Property(product => product.Price).Precision = 10;
    modelBuilder.Entity<Product>().Property(product => product.Price).Scale = 2;
}

আপনি যখন আপনার সমস্ত দাম-সম্পর্কিত বৈশিষ্ট্যগুলি সহ এটি করতে হয় তবে এটি বেশ ক্লান্তিকর কোড, তাই আমি এটি নিয়ে এসেছি:

    protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
    {
        var properties = new[]
        {
            modelBuilder.Entity<Product>().Property(product => product.Price),
            modelBuilder.Entity<Order>().Property(order => order.OrderTotal),
            modelBuilder.Entity<OrderDetail>().Property(detail => detail.Total),
            modelBuilder.Entity<Option>().Property(option => option.Price)
        };

        properties.ToList().ForEach(property =>
        {
            property.Precision = 10;
            property.Scale = 2;
        });

        base.OnModelCreating(modelBuilder);
    }

এটি ভাল অনুশীলন যে আপনি যখন কোনও পদ্ধতিকে ওভাররাইড করেন তখন বেস পদ্ধতিটি কল করেন, যদিও বেস বাস্তবায়ন কিছুই করে না।

আপডেট: এই নিবন্ধটি খুব সহায়ক ছিল।


10
ধন্যবাদ, এটি আমাকে সঠিক দিকে নির্দেশ করেছে। সিটিপি 5-তে সিনট্যাক্স একই বিবৃতিতে যথার্থতা এবং স্কেল যোগ করার অনুমতি দিতে পরিবর্তিত হয়েছে: মডেল বিল্ডার Eমান্তি <প্রোডাক্ট> () rop
কর্নেল

2
তবুও, আপনি সমস্ত দশমিকের জন্য সেট করতে পারেন এমন কোনও ধরণের "ডিফল্ট" থাকা ভাল না ?
ডেভ ভ্যান ডেন এয়েণ্ডে

3
আমি কলিং base.OnModelCreating(modelBuilder);প্রয়োজনীয় বলে মনে করি না । ভিএস-এর ডিবি কনটেক্সট মেটাডেটা থেকে: The default implementation of this method does nothing, but it can be overridden in a derived class such that the model can be further configured before it is locked down.
ম্যাট জেনকিন্স

@ ম্যাট: এটি দুর্দান্ত, তবে একজন বাস্তবায়নকারী হিসাবে আমার এদিকে যত্ন নেওয়া উচিত নয় এবং সবসময় বেসটি কল করা উচিত।
ডেভ ভ্যান ডেন আইন্দে

@ ডেভ এবং @ ম্যাট: একটি মন্তব্য ছিল এটি বেসকে কল করা "গুরুত্বপূর্ণ"। এটি একটি ভাল অনুশীলন, তবে যখন ইএফ উত্সটির খালি বাস্তবায়ন হয়, তখন এটি গুরুত্বপূর্ণ বলে দাবি করা বিভ্রান্তিকর। এটি বেস কী করে তা ভেবে মানুষকে ছেড়ে দেয়। আমি কী কৌতূহল ছিল আমি কি তা গুরুত্বপূর্ণ ছিল তা পরীক্ষা করতে ef5.0 এ ছড়িয়ে দিয়েছি। সেখানে কিছুই নেই. তাই শুধু একটি ভাল অভ্যাস।
ফিল soady

30

সত্তা ফ্রেমওয়ার্ক ভের 6 (আলফা, আরসি 1) এর কাস্টম কনভেনশন নামে পরিচিত । দশমিক নির্ভুলতা সেট করতে:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Properties<decimal>().Configure(config => config.HasPrecision(18, 4));
}

রেফারেন্স:


22
[Column(TypeName = "decimal(18,2)")]

এখানে বর্ণিত হিসাবে এটি ইএফ কোর কোডের সাথে প্রথম মাইগ্রেশন নিয়ে কাজ করবে ।


1
আপনি যদি কেবল এটি আপনার মডেলটিতে যুক্ত করেন তবে আপনি পেতে পারেনThe store type 'decimal(18,2)' could not be found in the SqlServer provider manifest
সেভেজ

@ সাভেজ দেখে মনে হচ্ছে এটি আপনার ডাটাবেস সরবরাহকারীর সাথে বা ডাটাবেসের সংস্করণে সমস্যা
এলনূর

@ এলনুর সেভেজ সঠিক, এটি EF মাইগ্রেশন 6..x এ একটি ত্রুটি ফেলবে উত্তরাধিকার, নন-কোর সংস্করণ কলাম অ্যাট্রিবিউটের মাধ্যমে নির্ভুলতা / স্কেল নির্দিষ্ট করার পক্ষে সমর্থন করে না এবং আপনি যদি ডেটা টাইপ বৈশিষ্ট্যটি ব্যবহার করেন তবে কিছুই করেনি (ডিফল্ট 18,2) does এটিএফ 6.x এ অ্যাট্রিবিউটের মাধ্যমে এটিকে কাজ করার জন্য আপনাকে মডেলবিল্ডারের কাছে নিজের এক্সটেনশনটি প্রয়োগ করতে হবে।
ক্রিস মোসচিনি

1
@ ক্রিসমোসচিনি, আমি আমার উত্তরটি EF কোর উল্লেখ করে পরিবর্তন করেছি। ধন্যবাদ
ইলনূর

14

এই কোড লাইনটি এটি সম্পাদন করার সহজ উপায় হতে পারে:

 public class ProductConfiguration : EntityTypeConfiguration<Product>
    {
        public ProductConfiguration()
        {
            this.Property(m => m.Price).HasPrecision(10, 2);
        }
    }

9

- EF কোর জন্য - সহ System.ComponentModel.DataAnnotations ব্যবহার করা;

ব্যবহার [Column( TypeName = "decimal( নির্ভুলতা , স্কেল )")]

যথার্থতা = ব্যবহৃত অক্ষরের মোট সংখ্যা

স্কেল = বিন্দুর পরে মোট সংখ্যা। (বিভ্রান্ত করা সহজ)

উদাহরণ :

public class Blog
{
    public int BlogId { get; set; }
    [Column(TypeName = "varchar(200)")]
    public string Url { get; set; }
    [Column(TypeName = "decimal(5, 2)")]
    public decimal Rating { get; set; }
}

আরও বিশদ এখানে: https://docs.microsoft.com/en-us/ef/core/modeling/relational/data-tyype


3

EF6 এ

modelBuilder.Properties()
    .Where(x => x.GetCustomAttributes(false).OfType<DecimalPrecisionAttribute>().Any())
    .Configure(c => {
        var attr = (DecimalPrecisionAttribute)c.ClrPropertyInfo.GetCustomAttributes(typeof (DecimalPrecisionAttribute), true).FirstOrDefault();

        c.HasPrecision(attr.Precision, attr.Scale);
    });

এই উত্তরটি এমন একটি অন্য উত্তরের আপগ্রেড বলে মনে হচ্ছে যা বৈশিষ্ট্যটি সংজ্ঞায়িত করে, আপনার এটিকে সেই উত্তরে সম্পাদনা করা উচিত
Rhys Bevilaqua

3

আপনি সর্বদা EF কে অনমোডেলক্রিয়াটিং ফাংশনে প্রসঙ্গ শ্রেণিতে কনভেনশনগুলির সাথে এটি করতে বলতে পারেন:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    // <... other configurations ...>
    // modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    // modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
    // modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

    // Configure Decimal to always have a precision of 18 and a scale of 4
    modelBuilder.Conventions.Remove<DecimalPropertyConvention>();
    modelBuilder.Conventions.Add(new DecimalPropertyConvention(18, 4));

    base.OnModelCreating(modelBuilder);
}

এটি কেবল কোড ফার্স্ট ইএফ ফাইয়ের ক্ষেত্রেই প্রযোজ্য এবং ডিবিতে ম্যাপযুক্ত সমস্ত দশমিক ধরণের ক্ষেত্রে প্রযোজ্য।


Remove<DecimalPropertyConvention>();প্রভুর আগে না আসা পর্যন্ত এটি কাজ করছিল না Add(new DecimalPropertyConvention(18, 4));। আমি মনে করি এটি আশ্চর্যজনক যে কেবল স্বয়ংক্রিয়ভাবে ওভাররাইড হয় না।
মাইক ডি ক্লার্ক

2

ব্যবহার

System.ComponentModel.DataAnnotations;

আপনি কেবল নিজের মডেলটিতে সেই বৈশিষ্ট্যটি রাখতে পারেন:

[DataType("decimal(18,5)")]

1
এটি পাঠযোগ্যতা এবং সরলতার জন্য সবচেয়ে সহজ বাস্তবায়ন। এই প্রোগ্রামটিতে
ransems

11
প্রতি এমএসডিএন.মাইক্রোসফট.ইন- ইউএস / লিবারি /jj591583(v=vs.113).aspx , এই উত্তরটি সত্যই ভুল। "কলামের টাইপনাম বৈশিষ্ট্যটি ডেটা টাইপ ডেটাঅ্যানোটেশনের সাথে গুলিয়ে ফেলবেন না Data
স্পেকলেডকার্প

2
@ ক্রমগুলি আমিও এটি ভেবেছিলাম, যতক্ষণ না আমি কেবল এটি পরীক্ষা করেছি এবং যেমন উপরে বলা হয়েছিল, এটি কোডফার্সের পক্ষে কাজ করে না এবং ডাটাবেসে স্থানান্তরিত করে না
RoLYroLLs

1

আপনি এমএসডিএন - সত্ত্বার ডেটা মডেলের দিকটি সম্পর্কে আরও তথ্য পেতে পারেন। http://msdn.microsoft.com/en-us/library/ee382834.aspx সম্পূর্ণ প্রস্তাবিত।


এটি দুর্দান্ত এবং সব কিছু, তবে কীভাবে এটি কোড-ফার্স্টের সাথে সম্পর্কিত?
ডেভ ভ্যান ডেন এয়েন্দে

এটি দরকারী তবে আমি একটি দশমিকের জন্য এখনও একটি [যথার্থ] বৈশিষ্ট্য নির্দিষ্ট করতে পারি না। সুতরাং আমি @ কিনস্লেয়ারুওয়াই দ্বারা সরবরাহিত সমাধানটি ব্যবহার করেছি।
কলিন

1

সত্ত্বা ফ্রেমওয়ার্ককোর জন্য প্রকৃত 3.1.3:

অনমোডেলক্রিয়েটিংয়ে কিছু সমাধান:

var fixDecimalDatas = new List<Tuple<Type, Type, string>>();
foreach (var entityType in builder.Model.GetEntityTypes())
{
    foreach (var property in entityType.GetProperties())
    {
        if (Type.GetTypeCode(property.ClrType) == TypeCode.Decimal)
        {
            fixDecimalDatas.Add(new Tuple<Type, Type, string>(entityType.ClrType, property.ClrType, property.GetColumnName()));
        }
    }
}

foreach (var item in fixDecimalDatas)
{
    builder.Entity(item.Item1).Property(item.Item2, item.Item3).HasColumnType("decimal(18,4)");
}

//custom decimal nullable:
builder.Entity<SomePerfectEntity>().Property(x => x.IsBeautiful).HasColumnType("decimal(18,4)");

0

কিনস্লেয়ারইউয়ের কাস্টম অ্যাট্রিবিউটটি আমার পক্ষে দুর্দান্তভাবে কাজ করেছে তবে কমপ্লেক্সটাইপগুলিতে আমার সমস্যা ছিল। এট্রিবিউট কোডে তাদের সত্ত্বা হিসাবে ম্যাপ করা হচ্ছে তাই কমপ্লেক্সটাইপ হিসাবে ম্যাপ করা যায় না।

তাই আমি এর জন্য অনুমতি দেওয়ার জন্য কোডটি বাড়িয়েছি:

public static void OnModelCreating(DbModelBuilder modelBuilder)
    {
        foreach (Type classType in from t in Assembly.GetAssembly(typeof(DecimalPrecisionAttribute)).GetTypes()
                                   where t.IsClass && t.Namespace == "FA.f1rstval.Data"
                                   select t)
        {
            foreach (var propAttr in classType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.GetCustomAttribute<DecimalPrecisionAttribute>() != null).Select(
                   p => new { prop = p, attr = p.GetCustomAttribute<DecimalPrecisionAttribute>(true) }))
            {

                ParameterExpression param = ParameterExpression.Parameter(classType, "c");
                Expression property = Expression.Property(param, propAttr.prop.Name);
                LambdaExpression lambdaExpression = Expression.Lambda(property, true,
                                                                         new ParameterExpression[] { param });
                DecimalPropertyConfiguration decimalConfig;
                int MethodNum;
                if (propAttr.prop.PropertyType.IsGenericType && propAttr.prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                {
                    MethodNum = 7;
                }
                else
                {
                    MethodNum = 6;
                }

                //check if complextype
                if (classType.GetCustomAttribute<ComplexTypeAttribute>() != null)
                {
                    var complexConfig = modelBuilder.GetType().GetMethod("ComplexType").MakeGenericMethod(classType).Invoke(modelBuilder, null);
                    MethodInfo methodInfo = complexConfig.GetType().GetMethods().Where(p => p.Name == "Property").ToList()[MethodNum];
                    decimalConfig = methodInfo.Invoke(complexConfig, new[] { lambdaExpression }) as DecimalPropertyConfiguration;
                }
                else
                {
                    var entityConfig = modelBuilder.GetType().GetMethod("Entity").MakeGenericMethod(classType).Invoke(modelBuilder, null);
                    MethodInfo methodInfo = entityConfig.GetType().GetMethods().Where(p => p.Name == "Property").ToList()[MethodNum];
                    decimalConfig = methodInfo.Invoke(entityConfig, new[] { lambdaExpression }) as DecimalPropertyConfiguration;
                }

                decimalConfig.HasPrecision(propAttr.attr.Precision, propAttr.attr.Scale);
            }
        }
    }

0

@ মার্ক 700, আমি ডিবিসেট <> ডিবি কনটেক্সট এর বৈশিষ্ট্যগুলি চালনার জন্য প্রকার নির্বাচনের মানদণ্ড পরিবর্তন করেছি। আমি এটি নিরাপদ বলে মনে করি কারণ এমন সময় আছে যখন আপনি প্রদত্ত নেমস্পেসে ক্লাস করেন যা মডেল সংজ্ঞাটির অংশ না হওয়া উচিত বা সেগুলি কিন্তু সত্ত্বা নয়। অথবা আপনার সত্তা পৃথক নেমস্পেসে বা পৃথক অ্যাসেমব্লিতে থাকতে পারে এবং এক সাথে প্রসঙ্গের মধ্যে টানতে পারে।

এছাড়াও, অসম্ভব সম্ভাবনা সত্ত্বেও, আমি মনে করি না যে এটি পদ্ধতি সংজ্ঞাগুলির ক্রমানুসারে নির্ভর করা নিরাপদ, সুতরাং পরামিতি তালিকা দ্বারা সেগুলি এড়ানো ভাল। (.GETTypeMethods () হ'ল একটি এক্সটেনশন পদ্ধতি যা আমি নতুন টাইপআইনফোর দৃষ্টান্তের সাথে কাজ করার জন্য তৈরি করেছি এবং পদ্ধতিগুলি সন্ধান করার সময় বর্গের স্তরক্রমকে সমতল করতে পারি)।

মনে রাখবেন যে অনমোডেল ক্রিয়েটিং এই পদ্ধতিতে প্রতিনিধি:

    private void OnModelCreatingSetDecimalPrecisionFromAttribute(DbModelBuilder modelBuilder)
    {
        foreach (var iSetProp in this.GetType().GetTypeProperties(true))
        {
            if (iSetProp.PropertyType.IsGenericType
                    && (iSetProp.PropertyType.GetGenericTypeDefinition() == typeof(IDbSet<>) || iSetProp.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>)))
            {
                var entityType = iSetProp.PropertyType.GetGenericArguments()[0];

                foreach (var propAttr in entityType
                                        .GetProperties(BindingFlags.Public | BindingFlags.Instance)
                                        .Select(p => new { prop = p, attr = p.GetCustomAttribute<DecimalPrecisionAttribute>(true) })
                                        .Where(propAttr => propAttr.attr != null))
                {
                    var entityTypeConfigMethod = modelBuilder.GetType().GetTypeInfo().DeclaredMethods.First(m => m.Name == "Entity");
                    var entityTypeConfig = entityTypeConfigMethod.MakeGenericMethod(entityType).Invoke(modelBuilder, null);

                    var param = ParameterExpression.Parameter(entityType, "c");
                    var lambdaExpression = Expression.Lambda(Expression.Property(param, propAttr.prop.Name), true, new ParameterExpression[] { param });

                    var propertyConfigMethod =
                        entityTypeConfig.GetType()
                            .GetTypeMethods(true, false)
                            .First(m =>
                            {
                                if (m.Name != "Property")
                                    return false;

                                var methodParams = m.GetParameters();

                                return methodParams.Length == 1 && methodParams[0].ParameterType == lambdaExpression.GetType();
                            }
                            );

                    var decimalConfig = propertyConfigMethod.Invoke(entityTypeConfig, new[] { lambdaExpression }) as DecimalPropertyConfiguration;

                    decimalConfig.HasPrecision(propAttr.attr.Precision, propAttr.attr.Scale);
                }
            }
        }
    }



    public static IEnumerable<MethodInfo> GetTypeMethods(this Type typeToQuery, bool flattenHierarchy, bool? staticMembers)
    {
        var typeInfo = typeToQuery.GetTypeInfo();

        foreach (var iField in typeInfo.DeclaredMethods.Where(fi => staticMembers == null || fi.IsStatic == staticMembers))
            yield return iField;

        //this bit is just for StaticFields so we pass flag to flattenHierarchy and for the purpose of recursion, restrictStatic = false
        if (flattenHierarchy == true)
        {
            var baseType = typeInfo.BaseType;

            if ((baseType != null) && (baseType != typeof(object)))
            {
                foreach (var iField in baseType.GetTypeMethods(true, staticMembers))
                    yield return iField;
            }
        }
    }

আমি ঠিক বুঝতে পেরেছি যে এই পদ্ধতির মাধ্যমে আমি কমপ্লেক্সটাইপগুলির সাথে ডিল করি নি। পরে এটি সংশোধন করবে।
এনিয়েওলা

তবে ব্রায়ানের প্রস্তাবিত সমাধানটি সহজ, মার্জিত এবং কাজ করে। আমি পারফরম্যান্স সম্পর্কে কোনও স্পষ্টিকর বক্তব্য দেব না তবে ইতিমধ্যে প্রতিফলিত প্রপার্টি ইনফোর বাইরে চলে যাওয়া আপনার নিজের শিকারের চেয়ে খুব বড় মডেলগুলিতে আরও ভাল পারফরম্যান্স অর্জন করতে পারে (200 এবং তত উপরে ক্রম অনুসারে)।
এনিওলা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.