Ustawianie unikalnych ograniczeń za pomocą płynnego API?
Próbuję zbudować encję EF z kodem i {[0] } używając płynnego API. tworzenie kluczy podstawowych jest łatwe, ale nie tak z unikalnym ograniczeniem. Widziałem stare posty, które sugerowały wykonywanie natywnych poleceń SQL w tym celu, ale to wydaje się pokonać cel. czy jest to możliwe z EF6?
6 answers
Na EF6. 2 , możesz użyć HasIndex()
, Aby dodać indeksy do migracji za pośrednictwem fluent API.
Https://github.com/aspnet/EntityFramework6/issues/274
Przykład
modelBuilder
.Entity<User>()
.HasIndex(u => u.Email)
.IsUnique();
Na EF6. 1 począwszy, możesz użyć IndexAnnotation()
, aby dodać indeksy do migracji w swoim płynnym API.
Http://msdn.microsoft.com/en-us/data/jj591617.aspx#PropertyIndex
Należy dodać odniesienie do:
using System.Data.Entity.Infrastructure.Annotations;
Podstawowe Przykład
Oto prosty sposób użycia, dodanie indeksu do właściwości User.FirstName
modelBuilder
.Entity<User>()
.Property(t => t.FirstName)
.HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute()));
Przykład Praktyczny:
Oto bardziej realistyczny przykład. Dodaje unikalny indeks na wielu właściwościach:User.FirstName
i User.LastName
, z nazwą indeksu "IX_FIrstNameLastName"
modelBuilder
.Entity<User>()
.Property(t => t.FirstName)
.IsRequired()
.HasMaxLength(60)
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(
new IndexAttribute("IX_FirstNameLastName", 1) { IsUnique = true }));
modelBuilder
.Entity<User>()
.Property(t => t.LastName)
.IsRequired()
.HasMaxLength(60)
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(
new IndexAttribute("IX_FirstNameLastName", 2) { IsUnique = true }));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-28 19:18:49
Jako dodatek do odpowiedzi Yorro, można to również zrobić za pomocą atrybutów.
Próbka dla int
wpisz unikalną kombinację klawiszy:
[Index("IX_UniqueKeyInt", IsUnique = true, Order = 1)]
public int UniqueKeyIntPart1 { get; set; }
[Index("IX_UniqueKeyInt", IsUnique = true, Order = 2)]
public int UniqueKeyIntPart2 { get; set; }
Jeżeli typem danych jest string
, to MaxLength
należy dodać atrybut:
[Index("IX_UniqueKeyString", IsUnique = true, Order = 1)]
[MaxLength(50)]
public string UniqueKeyStringPart1 { get; set; }
[Index("IX_UniqueKeyString", IsUnique = true, Order = 2)]
[MaxLength(50)]
public string UniqueKeyStringPart2 { get; set; }
Jeśli istnieje problem separacji modelu domeny/magazynu, użycie atrybutu / klasy Metadatatype
może być opcją: https://msdn.microsoft.com/en-us/library/ff664465%28v=pandp.50%29.aspx?f=255&MSPPError=-2147217396
Szybka aplikacja konsoli przykład:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
namespace EFIndexTest
{
class Program
{
static void Main(string[] args)
{
using (var context = new AppDbContext())
{
var newUser = new User { UniqueKeyIntPart1 = 1, UniqueKeyIntPart2 = 1, UniqueKeyStringPart1 = "A", UniqueKeyStringPart2 = "A" };
context.UserSet.Add(newUser);
context.SaveChanges();
}
}
}
[MetadataType(typeof(UserMetadata))]
public class User
{
public int Id { get; set; }
public int UniqueKeyIntPart1 { get; set; }
public int UniqueKeyIntPart2 { get; set; }
public string UniqueKeyStringPart1 { get; set; }
public string UniqueKeyStringPart2 { get; set; }
}
public class UserMetadata
{
[Index("IX_UniqueKeyInt", IsUnique = true, Order = 1)]
public int UniqueKeyIntPart1 { get; set; }
[Index("IX_UniqueKeyInt", IsUnique = true, Order = 2)]
public int UniqueKeyIntPart2 { get; set; }
[Index("IX_UniqueKeyString", IsUnique = true, Order = 1)]
[MaxLength(50)]
public string UniqueKeyStringPart1 { get; set; }
[Index("IX_UniqueKeyString", IsUnique = true, Order = 2)]
[MaxLength(50)]
public string UniqueKeyStringPart2 { get; set; }
}
public class AppDbContext : DbContext
{
public virtual DbSet<User> UserSet { get; set; }
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-20 17:49:36
Oto metoda rozszerzenia pozwalająca na płynniejsze ustawianie unikalnych indeksów:
public static class MappingExtensions
{
public static PrimitivePropertyConfiguration IsUnique(this PrimitivePropertyConfiguration configuration)
{
return configuration.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute { IsUnique = true }));
}
}
Użycie:
modelBuilder
.Entity<Person>()
.Property(t => t.Name)
.IsUnique();
Wygeneruje migrację np.:
public partial class Add_unique_index : DbMigration
{
public override void Up()
{
CreateIndex("dbo.Person", "Name", unique: true);
}
public override void Down()
{
DropIndex("dbo.Person", new[] { "Name" });
}
}
Src: tworzenie unikalnego indeksu z Entity Framework 6.1 fluent API
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:39
@ coni2k 's answer is correct however you must add [StringLength]
atrybut for it work bo inaczej otrzymasz nieprawidłowy wyjątek klucza (przykład poniżej).
[StringLength(65)]
[Index("IX_FirstNameLastName", 1, IsUnique = true)]
public string FirstName { get; set; }
[StringLength(65)]
[Index("IX_FirstNameLastName", 2, IsUnique = true)]
public string LastName { get; set; }
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-30 20:41:55
Niestety nie jest to obsługiwane w encji Framework. To było na mapie drogowej dla EF 6, ale został przesunięty z powrotem: Workitem 299: unikalne ograniczenia (unikalne indeksy)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-05 11:59:19
Tymczasem jest to:
Przepraszam za nie kopiowanie kodu, jest on trochę długi.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-02 01:47:06