Entity Framework Code First Fluent Api : 열에 강화 추가
EF 4.2 CF를 중이며 POCO 개체의 특정 실행 열에 만들고 싶습니다.
예를 들어 다음과 같은 직원 클래스가 가정 해 보겠습니다.
public class Employee
{
public int EmployeeID { get; set; }
public string EmployeeCode { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime HireDate { get; set; }
}
우리는 종종 직원을 EmployeeCode로 검색하고 직원이 많기 때문에 성과 좋상의 색인을 만드는 것이 좋습니다.
어떻게 든 유창한 API로 할 수 있습니까? 또는 아마도 데이터 주석?
다음과 같은 SQL 명령을 사용할 수 있습니다.
context.Database.ExecuteSqlCommand("CREATE INDEX IX_NAME ON ...");
나는 그런 원시 SQL을 피하고 싶습니다.
나는 라인을 따라하는 것이 존재하지 않습니다.
class EmployeeConfiguration : EntityTypeConfiguration<Employee>
{
internal EmployeeConfiguration()
{
this.HasIndex(e => e.EmployeeCode)
.HasIndex(e => e.FirstName)
.HasIndex(e => e.LastName);
}
}
또는 System.ComponentModel.DataAnnotations
POCO를 사용 하면 다음과 같이 보일 수 있습니다 (다시 말하지만 존재하지 않는다는 것을 알고 있습니다).
public class Employee
{
public int EmployeeID { get; set; }
[Indexed]
public string EmployeeCode { get; set; }
[Indexed]
public string FirstName { get; set; }
[Indexed]
public string LastName { get; set; }
public DateTime HireDate { get; set; }
}
누구 든지이 작업을 수행하는 방법에 대한 아이디어가 수행이를 수행하는 방법을 구현할 계획이있는 경우 코드를 먼저 사용하고 있습니까?
업데이트 : Robba의 답변에서 언급 했듯이이 기능은 EF 버전 6.1에서 구현됩니다.
마이그레이션이 EF 4.3에 도입 된 후 이제 테이블을 수정하거나 만들 때 보안을 추가 할 수 있습니다. 다음은 ADO.NET 팀 블로그 의 EF 4.3 코드 기반 마이그레이션 연습 에서 발췌 한 것입니다.
namespace MigrationsCodeDemo.Migrations
{
using System.Data.Entity.Migrations;
public partial class AddPostClass : DbMigration
{
public override void Up()
{
CreateTable(
"Posts",
c => new
{
PostId = c.Int(nullable: false, identity: true),
Title = c.String(maxLength: 200),
Content = c.String(),
BlogId = c.Int(nullable: false),
})
.PrimaryKey(t => t.PostId)
.ForeignKey("Blogs", t => t.BlogId, cascadeDelete: true)
.Index(t => t.BlogId)
.Index(p => p.Title, unique: true);
AddColumn("Blogs", "Rating", c => c.Int(nullable: false, defaultValue: 3));
}
public override void Down()
{
DropIndex("Posts", new[] { "BlogId" });
DropForeignKey("Posts", "BlogId", "Blogs");
DropColumn("Blogs", "Rating");
DropTable("Posts");
}
}
}
이것은 내가 처음 질문을 올렸을 때 찾던 색인을 추가하는 강력한 형식의 좋은 방법입니다.
인덱싱 된 (제안한대로) 속성을 만든 다음 사용자 지정 이니셜 라이저에서 선택할 수 있습니다.
다음 속성을 만들었습니다.
[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
public class IndexAttribute : Attribute
{
public IndexAttribute(bool isUnique = false, bool isClustered = false, SortOrder sortOrder = SortOrder.Ascending)
{
IsUnique = isUnique;
IsClustered = isClustered;
SortOrder = sortOrder == SortOrder.Unspecified ? SortOrder.Ascending : sortOrder;
}
public bool IsUnique { get; private set; }
public bool IsClustered { get; private set; }
public SortOrder SortOrder { get; private set; }
//public string Where { get; private set; }
}
그런 다음 내 생성 된 테이블 이름 목록을 가져올 사용자 지정 이니셜 라이저를 만들었습니다. 모든 것이 상속하는 두 개의 기본 클래스가 있으므로 다음을 수행하여 테이블 이름을 얻었습니다.
var baseEF = typeof (BaseEFEntity);
var baseLink = typeof (BaseLinkTable);
var types =
AppDomain.CurrentDomain.GetAssemblies().ToList().SelectMany(s => s.GetTypes()).Where(
baseEF.IsAssignableFrom).Union(AppDomain.CurrentDomain.GetAssemblies().ToList().SelectMany(
s => s.GetTypes()).Where(
baseLink.IsAssignableFrom));
var sqlScript = context.ObjectContext.CreateDatabaseScript();
foreach (var type in types)
{
var table = (TableAttribute) type.GetCustomAttributes(typeof (TableAttribute), true).FirstOrDefault();
var tableName = (table != null ? table.Name : null) ?? Pluralizer.Pluralize(type.Name);
그런 다음이 특성이있는 각 엔터티에서 모든 속성을 속성 다음 SQL 명령을 실행하여 각 속성에 대한 보안을 생성합니다. 단!
//Check that a table exists
if (sqlScript.ToLower().Contains(string.Format(CREATETABLELOOKUP, tableName.ToLower())))
{
//indexes
var indexAttrib = typeof (IndexAttribute);
properties = type.GetProperties().Where(prop => Attribute.IsDefined(prop, indexAttrib));
foreach (var property in properties)
{
var attributes = property.GetCustomAttributes(indexAttrib, true).ToList();
foreach (IndexAttribute index in attributes)
{
var indexName = string.Format(INDEXNAMEFORMAT, tableName, property.Name,
attributes.Count > 1
? UNDERSCORE + (attributes.IndexOf(index) + 1)
: string.Empty);
try
{
context.ObjectContext.ExecuteStoreCommand(
string.Format(INDEX_STRING, indexName,
tableName,
property.Name,
index.IsUnique ? UNIQUE : string.Empty,
index.IsClustered ? CLUSTERED : NONCLUSTERED,
index.SortOrder == SortOrder.Ascending ? ASC : DESC));
}
catch (Exception)
{
}
}
}
고유 한 제약 조건 및 기본 제약 조건을 적용 할 수 있습니다. 또한 정말 좋은 점은 상속 된 클래스에있는 속성 또는 제약 조건이 상속 된 모든 클래스에 있습니다.
BTW 복수형 도우미에는 다음이 포함됩니다.
public static class Pluralizer
{
private static object _pluralizer;
private static MethodInfo _pluralizationMethod;
public static string Pluralize(string word)
{
CreatePluralizer();
return (string) _pluralizationMethod.Invoke(_pluralizer, new object[] {word});
}
public static void CreatePluralizer()
{
if (_pluralizer == null)
{
var aseembly = typeof (DbContext).Assembly;
var type =
aseembly.GetType(
"System.Data.Entity.ModelConfiguration.Design.PluralizationServices.EnglishPluralizationService");
_pluralizer = Activator.CreateInstance(type, true);
_pluralizationMethod = _pluralizer.GetType().GetMethod("Pluralize");
}
}
}
frozen의 응답을 바탕으로 마이그레이션하여 직접 코딩 할 수 있습니다.
먼저 패키지 관리자 콘솔로 이동하여 사용하여 새 마이그레이션 을 add-migration
만든 다음 이름을 지정합니다. 빈 마이그레이션이 나타납니다. 작성자 붙입니다 :
public override void Up()
{
CreateIndex("TableName", "ColumnName");
}
public override void Down()
{
DropIndex("TableName",new[] {"ColumnName"});
}
모바일 필드를 사용하는 경우 450 자 길이로 제한해야합니다.
나는 또한 최근에 제출 한 조사하고 다른 방법을 저장하기 때문에 데이터베이스를 시드 할 때 사용을 허가하는 데 사용했습니다.
public class MyDBInitializer : DropCreateDatabaseIfModelChanges<MyContext>
{
private MyContext _Context;
protected override void Seed(MyContext context)
{
base.Seed(context);
_Context = context;
// We create database indexes
CreateIndex("FieldName", typeof(ClassName));
context.SaveChanges();
}
private void CreateIndex(string field, Type table)
{
_Context.Database.ExecuteSqlCommand(String.Format("CREATE INDEX IX_{0} ON {1} ({0})", field, table.Name));
}
}
Entity Framework 6.1 (현재 베타 버전)에서는 Index Attribute를 지원하여 Code First 이전에서 (고유 한) 보안이 자동으로 생성되는 속성에 주석을 추가합니다.
Entity Framework 6.1 이상을 사용하는 모든 사용자는 유창한 API로 다음을 수행 할 수 있습니다.
modelBuilder
.Entity<Department>()
.Property(t => t.Name)
.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute()));
문서 에서 더 많은 것을 발견했습니다 .
온라인에서 솔루션을 찾아 내 요구 사항에 맞게 조정했습니다.
[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
public class IndexAttribute : Attribute
{
public IndexAttribute(string name, bool unique = false)
{
this.Name = name;
this.IsUnique = unique;
}
public string Name { get; private set; }
public bool IsUnique { get; private set; }
}
public class IndexInitializer<T> : IDatabaseInitializer<T> where T : DbContext
{
private const string CreateIndexQueryTemplate = "CREATE {unique} INDEX {indexName} ON {tableName} ({columnName});";
public void InitializeDatabase(T context)
{
const BindingFlags PublicInstance = BindingFlags.Public | BindingFlags.Instance;
Dictionary<IndexAttribute, List<string>> indexes = new Dictionary<IndexAttribute, List<string>>();
string query = string.Empty;
foreach (var dataSetProperty in typeof(T).GetProperties(PublicInstance).Where(p => p.PropertyType.Name == typeof(DbSet<>).Name))
{
var entityType = dataSetProperty.PropertyType.GetGenericArguments().Single();
TableAttribute[] tableAttributes = (TableAttribute[])entityType.GetCustomAttributes(typeof(TableAttribute), false);
indexes.Clear();
string tableName = tableAttributes.Length != 0 ? tableAttributes[0].Name : dataSetProperty.Name;
foreach (PropertyInfo property in entityType.GetProperties(PublicInstance))
{
IndexAttribute[] indexAttributes = (IndexAttribute[])property.GetCustomAttributes(typeof(IndexAttribute), false);
NotMappedAttribute[] notMappedAttributes = (NotMappedAttribute[])property.GetCustomAttributes(typeof(NotMappedAttribute), false);
if (indexAttributes.Length > 0 && notMappedAttributes.Length == 0)
{
ColumnAttribute[] columnAttributes = (ColumnAttribute[])property.GetCustomAttributes(typeof(ColumnAttribute), false);
foreach (IndexAttribute indexAttribute in indexAttributes)
{
if (!indexes.ContainsKey(indexAttribute))
{
indexes.Add(indexAttribute, new List<string>());
}
if (property.PropertyType.IsValueType || property.PropertyType == typeof(string))
{
string columnName = columnAttributes.Length != 0 ? columnAttributes[0].Name : property.Name;
indexes[indexAttribute].Add(columnName);
}
else
{
indexes[indexAttribute].Add(property.PropertyType.Name + "_" + GetKeyName(property.PropertyType));
}
}
}
}
foreach (IndexAttribute indexAttribute in indexes.Keys)
{
query += CreateIndexQueryTemplate.Replace("{indexName}", indexAttribute.Name)
.Replace("{tableName}", tableName)
.Replace("{columnName}", string.Join(", ", indexes[indexAttribute].ToArray()))
.Replace("{unique}", indexAttribute.IsUnique ? "UNIQUE" : string.Empty);
}
}
if (context.Database.CreateIfNotExists())
{
context.Database.ExecuteSqlCommand(query);
}
}
private string GetKeyName(Type type)
{
PropertyInfo[] propertyInfos = type.GetProperties(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public);
foreach (PropertyInfo propertyInfo in propertyInfos)
{
if (propertyInfo.GetCustomAttribute(typeof(KeyAttribute), true) != null)
return propertyInfo.Name;
}
throw new Exception("No property was found with the attribute Key");
}
}
그런 다음 dbcontext에서 OnModelCreating을 오버로드하십시오.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer(new IndexInitializer<MyContext>());
base.OnModelCreating(modelBuilder);
}
엔터티 유형에 적용되는 속성을 적용합니다.이 솔루션을 사용하면 적용 할 여러 필드가 동일한 이름과 고유 한 한 이름 만 사용할 수 있습니다.
위의 Tsuushin의 답변을 여러 열과 고유 한 제약 조건을 지원합니다.
private void CreateIndex(RBPContext context, string field, string table, bool unique = false)
{
context.Database.ExecuteSqlCommand(String.Format("CREATE {0}NONCLUSTERED INDEX IX_{1}_{2} ON {1} ({3})",
unique ? "UNIQUE " : "",
table,
field.Replace(",","_"),
field));
}
Petoj에서 확장
CreateIndexQueryTemplate을 다음과 같이 수정했습니다.
private const string CreateIndexQueryTemplate = "IF NOT EXISTS (SELECT name FROM sysindexes WHERE name = '{indexName}') CREATE {unique} INDEX {indexName} ON {tableName} ({columnName});";
OnModelCreating에서 다음을 제거했습니다.
Database.SetInitializer(new IndexInitializer<MyContext>());
구성 시드 방법에 다음을 추가했습니다.
new IndexInitializer<MyContext>().InitializeDatabase(context);
이런 식으로 데이터베이스 업데이트를 수행 할 때마다 보안이 실행됩니다.
이 기능을 EF에 추가 추가 비용 여기 http://entityframework.codeplex.com/workitem/57에서 투표 할 수 있습니다 .
jwsadler의 데이터 주석 확장은 우리에게 적합했습니다. 우리는 Annotations를 사용하여 클래스 또는 속성 처리에 영향을 미치고 Fluent API를 전역 변경에 사용합니다.
우리의 주석은하지 않고 (고유하지 않고 무시)와 getdate () 및 (1)의 내용을 포함합니다. 코드 샘플은 우리가 상황에 어떻게 적용했는지 보여줍니다. 모든 클래스는 하나의 기본 클래스에서 상속됩니다. 이 구현은 매우 간단한 모델이 있기 때문에 많은 가정을합니다. Entity Framework 6.0.1을 사용하고 있습니다. 많은 댓글이 포함되었습니다.
using System;
using System.Linq;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
namespace YourNameSpace
{
public enum SqlOption
{
Active = 1,
GetDate = 2,
Index = 3,
Unique = 4,
}
[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
public class SqlAttribute : Attribute
{
public SqlAttribute(SqlOption selectedOption = SqlOption.Index)
{
this.Option = selectedOption;
}
public SqlOption Option {get; set;}
}
// See enum above, usage examples: [Sql(SqlOption.Unique)] [Sql(SqlOption.Index)] [Sql(SqlOption.GetDate)]
public class SqlInitializer<T> : IDatabaseInitializer<T> where T : DbContext
{
// Create templates for the DDL we want generate
const string INDEX_TEMPLATE = "CREATE NONCLUSTERED INDEX IX_{columnName} ON [dbo].[{tableName}] ([{columnName}]);";
const string UNIQUE_TEMPLATE = "CREATE UNIQUE NONCLUSTERED INDEX UQ_{columnName} ON [dbo].[{tableName}] ([{columnName}]);";
const string GETDATE_TEMPLATE = "ALTER TABLE [dbo].[{tableName}] ADD DEFAULT (getdate()) FOR [{columnName}];";
const string ACTIVE_TEMPLATE = "ALTER TABLE [dbo].[{tableName}] ADD DEFAULT (1) FOR [{columnName}];";
// Called by Database.SetInitializer(new IndexInitializer< MyDBContext>()); in MyDBContext.cs
public void InitializeDatabase(T context)
{
// To be used for the SQL DDL that I generate
string sql = string.Empty;
// All of my classes are derived from my base class, Entity
var baseClass = typeof(Entity);
// Get a list of classes in my model derived from my base class
var modelClasses = AppDomain.CurrentDomain.GetAssemblies().ToList().
SelectMany(s => s.GetTypes()).Where(baseClass.IsAssignableFrom);
// For debugging only - examine the SQL DDL that Entity Framework is generating
// Manipulating this is discouraged.
var generatedDDSQL = ((IObjectContextAdapter)context).ObjectContext.CreateDatabaseScript();
// Define which Annotation Attribute we care about (this class!)
var annotationAttribute = typeof(SqlAttribute);
// Generate a list of concrete classes in my model derived from
// Entity class since we follow Table Per Concrete Class (TPC).
var concreteClasses = from modelClass in modelClasses
where !modelClass.IsAbstract
select modelClass;
// Iterate through my model's concrete classes (will be mapped to tables)
foreach (var concreteClass in concreteClasses)
{
// Calculate the table name - could get the table name from list of DbContext's properties
// to be more correct (but this is sufficient in my case)
var tableName = concreteClass.Name + "s";
// Get concrete class's properties that have this annotation
var propertiesWithAnnotations = concreteClass.GetProperties().Where(prop => Attribute.IsDefined(prop, annotationAttribute));
foreach (var annotatedProperty in propertiesWithAnnotations)
{
var columnName = annotatedProperty.Name;
var annotationProperties = annotatedProperty.GetCustomAttributes(annotationAttribute, true).ToList();
foreach (SqlAttribute annotationProperty in annotationProperties)
{
// Generate the appropriate SQL DLL based on the attribute selected
switch (annotationProperty.Option)
{
case SqlOption.Active: // Default value of true plus an index (for my case)
sql += ACTIVE_TEMPLATE.Replace("{tableName}", tableName).Replace("{columnName}", columnName);
sql += INDEX_TEMPLATE.Replace("{tableName}", tableName).Replace("{columnName}", columnName);
break;
case SqlOption.GetDate: // GetDate plus an index (for my case)
sql += GETDATE_TEMPLATE.Replace("{tableName}", tableName).Replace("{columnName}", columnName);
sql += INDEX_TEMPLATE.Replace("{tableName}", tableName).Replace("{columnName}", columnName);
break;
case SqlOption.Index: // Default for empty annotations for example [Sql()]
sql += INDEX_TEMPLATE.Replace("{tableName}", tableName).Replace("{columnName}", columnName);
break;
case SqlOption.Unique:
sql += UNIQUE_TEMPLATE.Replace("{tableName}", tableName).Replace("{columnName}", columnName);
break;
} // switch
} // foreach annotationProperty
} // foreach annotatedProperty
} // foreach concreteClass
// Would have been better not to go through all the work of generating the SQL
// if we weren't going to use it, but putting it here makes it easier to follow.
if (context.Database.CreateIfNotExists())
context.Database.ExecuteSqlCommand(sql);
} // InitializeDatabase
} // SqlInitializer
} // Namespace
융합은 다음과 가변적입니다.
using System;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
namespace YourNameSpace
{
public class MyDBContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Only including my concrete classes here as we're following Table Per Concrete Class (TPC)
public virtual DbSet<Attendance> Attendances { get; set; }
public virtual DbSet<Course> Courses { get; set; }
public virtual DbSet<Location> Locations { get; set; }
public virtual DbSet<PaymentMethod> PaymentMethods { get; set; }
public virtual DbSet<Purchase> Purchases { get; set; }
public virtual DbSet<Student> Students { get; set; }
public virtual DbSet<Teacher> Teachers { get; set; }
// Process the SQL Annotations
Database.SetInitializer(new SqlInitializer<MyDBContext>());
base.OnModelCreating(modelBuilder);
// Change all datetime columns to datetime2
modelBuilder.Properties<DateTime>().Configure(c => c.HasColumnType("datetime2"));
// Turn off cascading deletes
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
}
}
}
모든 훌륭한 응답을 추가로 구축하기 위해 사용할 메타 데이터 유형에서 인덱스 속성을 선택할 수 다음 코드를 추가했습니다. 자세한 내용 은 내 블로그 게시물을 참조 하세요. 여기에 요약 된 내용이 있습니다.
메타 데이터 유형은 다음과 같이 사용됩니다.
[MetadataType(typeof(UserAccountAnnotations))]
public partial class UserAccount : IDomainEntity
{
[Key]
public int Id { get; set; } // Unique ID
sealed class UserAccountAnnotations
{
[Index("IX_UserName", unique: true)]
public string UserName { get; set; }
}
}
이 예에서 메타 데이터 유형은 중첩 클래스이지만 반드시 그럴 필요는 없으며 모든 유형이 될 수 있습니다. 속성 일치는 이름으로 만 수행되므로 메타 데이터 유형에는 동일한 이름의 속성이 있어야하며 여기에 적용된 모든 데이터 주석은 연결된 엔터티 클래스에 적용되어야합니다. 연결된 메타 데이터 유형을 확인하지 않기 때문에 원래 솔루션에서는 작동하지 않았습니다. 다음 도우미 메서드로 연결했습니다.
/// <summary>
/// Gets the index attributes on the specified property and the same property on any associated metadata type.
/// </summary>
/// <param name="property">The property.</param>
/// <returns>IEnumerable{IndexAttribute}.</returns>
IEnumerable<IndexAttribute> GetIndexAttributes(PropertyInfo property)
{
Type entityType = property.DeclaringType;
var indexAttributes = (IndexAttribute[])property.GetCustomAttributes(typeof(IndexAttribute), false);
var metadataAttribute =
entityType.GetCustomAttribute(typeof(MetadataTypeAttribute)) as MetadataTypeAttribute;
if (metadataAttribute == null)
return indexAttributes; // No metadata type
Type associatedMetadataType = metadataAttribute.MetadataClassType;
PropertyInfo associatedProperty = associatedMetadataType.GetProperty(property.Name);
if (associatedProperty == null)
return indexAttributes; // No metadata on the property
var associatedIndexAttributes =
(IndexAttribute[])associatedProperty.GetCustomAttributes(typeof(IndexAttribute), false);
return indexAttributes.Union(associatedIndexAttributes);
}
@highace가 준 대답에 문제가 있음을 발견했습니다. 다운 마이그레이션이 DropIndex에 대해 잘못된 재정의를 사용합니다. 내가 한 일은 다음과 같습니다.
- 인덱스 열 (900 바이트)에 대한 SQL Server의 제한을 준수하기 위해 모델에서 몇 개의 필드 크기를 줄였습니다.
- Add-Migration "Add Unique Indexes"를 사용하여 마이그레이션을 추가했습니다.
- 마이그레이션에 CreateIndex 및 DropIndex 메서드를 수동으로 추가했습니다. 단일 열 인덱스에 대한 인덱스 이름을 사용하는 재정의를 사용했습니다. 인덱스가 둘 이상의 열에 걸쳐있는 열 이름 배열을 사용하는 재정의를 사용했습니다.
그리고 다음은 각 메서드의 두 재정의 예제가있는 코드입니다.
public partial class AddUniqueIndexes : DbMigration
{
public override void Up()
{
//Sql Server limits indexes to 900 bytes,
//so we need to ensure cumulative field sizes do not exceed this
//otherwise inserts and updates could be prevented
//http://www.sqlteam.com/article/included-columns-sql-server-2005
AlterColumn("dbo.Answers",
"Text",
c => c.String(nullable: false, maxLength: 400));
AlterColumn("dbo.ConstructionTypes",
"Name",
c => c.String(nullable: false, maxLength: 300));
//[IX_Text] is the name that Entity Framework would use by default
// even if it wasn't specified here
CreateIndex("dbo.Answers",
"Text",
unique: true,
name: "IX_Text");
//Default name is [IX_Name_OrganisationID]
CreateIndex("dbo.ConstructionTypes",
new string[] { "Name", "OrganisationID" },
unique: true);
}
public override void Down()
{
//Drop Indexes before altering fields
//(otherwise it will fail because of dependencies)
//Example of dropping an index based on its name
DropIndex("dbo.Answers", "IX_Text");
//Example of dropping an index based on the columns it targets
DropIndex("dbo.ConstructionTypes",
new string[] { "Name", "OrganisationID" });
AlterColumn("dbo.ConstructionTypes",
"Name",
c => c.String(nullable: false));
AlterColumn("dbo.Answers",
"Text",
c => c.String(nullable: false, maxLength: 500));
}
EF7의 경우 hasIndex()
방법을 사용할 수 있습니다 . 클러스터형 및 비 클러스터형 인덱스도 설정할 수 있습니다. 기본적으로 기본 키는 클러스터됩니다. 우리도 그 행동을 바꿀 수 있습니다.
supplierItemEntity.HasKey(supplierItem => supplierItem.SupplierItemId).ForSqlServerIsClustered(false);
supplierItemEntity.HasIndex(s => new { s.ItemId }).ForSqlServerIsClustered(true);
'ProgramingTip' 카테고리의 다른 글
WebClient.DownloadString ()은 고유 한 문자가있는 곳을 반환합니다. (0) | 2020.11.26 |
---|---|
SQL Server 2008에 새 스키마를 추가하는 방법은 무엇입니까? (0) | 2020.11.26 |
변수가 한 노드 또는 다른 노드 같은지 확인하는 방법은 무엇입니까? (0) | 2020.11.26 |
날짜 형식은 날짜 형식을 날짜 형식화하지 않습니다. (0) | 2020.11.26 |
C # 사전 하나의 키 많은 값 (0) | 2020.11.26 |