Ok, dann machst du nur etwas falsch. Zusätzlich zu meinem Kommentar habe ich ein Beispiel für Ihr erstellt, das zeigt, dass EF standardmäßig keine Duplikate erstellt.
Ich habe zwei Klassen:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public ProductCategory Category { get; set; }
public decimal Price { get; set; }
}
public class ProductCategory
{
public int Id { get; set; }
public string Name { get; set; }
}
Ein Kontext:
public class MyContext : DbContext
{
public DbSet<Product> Products { get; set; }
public DbSet<ProductCategory> ProductCategories { get; set; }
public MyContext()
: base("name=MyContext")
{
}
public MyContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer<MyContext>(null);
// Table mappings
modelBuilder.Entity<Product>().ToTable("Product");
modelBuilder.Entity<ProductCategory>().ToTable("ProductCategory");
base.OnModelCreating(modelBuilder);
}
}
Dann eine initializer Klasse (dies von anderen Strategien erben könnte, wenn Sie wollen):
public class InitDb<TContext> : DropCreateDatabaseAlways<TContext>
where TContext : DbContext
{
}
Der Hauptprogramm:
static void Main(string[] args)
{
var prodCat = new ProductCategory()
{
Name = "Category 1"
};
var prod = new Product()
{
Name = "Product 1",
Category = prodCat,
Price = 19.95M
};
using (var context = new MyContext())
{
var initializer = new InitDb<MyContext>();
initializer.InitializeDatabase(context);
Console.WriteLine("Adding products and categories to context.");
context.ProductCategories.Add(prodCat);
context.Products.Add(prod);
Console.WriteLine();
Console.WriteLine("Saving initial context.");
context.SaveChanges();
Console.WriteLine("Context saved.");
Console.WriteLine();
Console.WriteLine("Changing product details.");
var initProd = context.Products.Include(x => x.Category).SingleOrDefault(x => x.Id == 1);
PrintProduct(initProd);
initProd.Name = "Product 1 modified";
initProd.Price = 29.95M;
initProd.Category.Name = "Category 1 modified";
PrintProduct(initProd);
Console.WriteLine();
Console.WriteLine("Saving modified context.");
context.SaveChanges();
Console.WriteLine("Context saved.");
Console.WriteLine();
Console.WriteLine("Getting modified product from database.");
var modProd = context.Products.Include(x => x.Category).SingleOrDefault(x => x.Id == 1);
PrintProduct(modProd);
Console.WriteLine();
Console.WriteLine("Finished!");
Console.ReadKey();
}
}
static void PrintProduct(Product prod)
{
Console.WriteLine(new string('-', 10));
Console.WriteLine("Id : {0}", prod.Id);
Console.WriteLine("Name : {0}", prod.Name);
Console.WriteLine("Price : {0}", prod.Price);
Console.WriteLine("CatId : {0}", prod.Category.Id);
Console.WriteLine("CatName : {0}", prod.Category.Name);
Console.WriteLine(new string('-', 10));
}
Daraus ergibt sich die folgende Ausgabe der Konsole:
Adding products and categories to context.
Saving initial context.
Context saved.
Changing product details.
----------
Id : 1
Name : Product 1
Price : 19,95
CatId : 1
CatName : Category 1
----------
----------
Id : 1
Name : Product 1 modified
Price : 29,95
CatId : 1
CatName : Category 1 modified
----------
Saving modified context.
Context saved.
Getting modified product from database.
----------
Id : 1
Name : Product 1 modified
Price : 29,95
CatId : 1
CatName : Category 1 modified
----------
Finished!
Auch wenn in SQL Server Management Studio, diese Lösung hat nur erstellt (und aktualisiert) ein Produkt und eine Kategorie suchen.
Natürlich sollten Sie mit Repositories arbeiten, um Ihre Daten und eine Arbeitseinheit abzurufen, zu aktualisieren und zu löschen. Diese wurden aus dem Beispiel weggelassen.
Also, wenn Sie keinen Code schreiben, können wir Ihnen nicht viel weiter helfen :-)
Können Sie den Code hinzufügen, in dem Sie die Daten erstellen? Wenn Ihre Referenzen in Ihren Klassen korrekt sind, sollte EF nur alle Instanzen einmal erstellen. – Nullius
Ja, es erstellt alle Instanzen gleichzeitig. Das ist das eigentliche Problem. Lassen Sie mich das Problem noch einmal erklären. Angenommen, ich habe eine Instanz von Product, in der sich eine ProductType-Instanz befindet. Angenommen, die Produktinstanz wurde bereits in der Vergangenheit beibehalten. Wenn ich versuche, diese Product-Instanz zu aktualisieren, erstellt EF eine doppelte ProductType-Instanz (was ein Fall ist, den ich nicht möchte), wenn ich den Status des ProductType-Attributs nicht auf Unverändert festlege. – Furkan