کار با کلیدهای اصلی و خارجی در EF Code first
نویسنده: وحید نصیری
تاریخ: ۱۳۹۱/۰۴/۱۹ ۱۷:۵۱
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
using System;
using System.Data.Entity;
using System.Data.Entity.Migrations;
namespace TestKeys
{
public class Bill
{
public int Id { get; set; }
public decimal Amount { set; get; }
public virtual Account Account { get; set; }
}
public class Account
{
public int Id { get; set; }
public string Name { get; set; }
}
public class MyContext : DbContext
{
public DbSet<Bill> Bills { get; set; }
public DbSet<Account> Accounts { get; set; }
}
public class Configuration : DbMigrationsConfiguration<MyContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
}
protected override void Seed(MyContext context)
{
var a1 = new Account { Name = "a1" };
var a2 = new Account { Name = "a2" };
var bill1 = new Bill { Amount = 100, Account = a1 };
var bill2 = new Bill { Amount = 200, Account = a2 };
context.Bills.Add(bill1);
context.Bills.Add(bill2);
base.Seed(context);
}
}
public static class Test
{
public static void Start()
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, Configuration>());
using (var ctx = new MyContext())
{
var bill1 = ctx.Bills.Find(1);
Console.WriteLine(bill1.Amount);
}
}
}
}
using (var ctx = new MyContext())
{
var bill1 = ctx.Bills.Find(1);
var a2 = new Account { Id = 2, Name = "a2" };
bill1.Account = a2;
ctx.SaveChanges();
}
using (var ctx = new MyContext())
{
var bill1 = ctx.Bills.Find(1);
var a2 = ctx.Accounts.Find(2);
bill1.Account = a2;
ctx.SaveChanges();
}
public class Bill
{
public int Id { get; set; }
public decimal Amount { set; get; }
[ForeignKey("AccountId")]
public virtual Account Account { get; set; }
public int AccountId { set; get; }
}
using (var ctx = new MyContext())
{
var bill1 = ctx.Bills.Find(1);
bill1.AccountId = 2;
ctx.SaveChanges();
}
using (var ctx = new MyContext())
{
var a2 = new Account { Id = 2, Name = "a2_a2" };
ctx.Entry(a2).State = System.Data.EntityState.Modified;
ctx.SaveChanges();
}
درود به آقای نصیری عزیز
بر اساس آموزههای شما پروژه ای در asp.net mvc4 و ef code firstو unitofwork نوشته ام اما برای وهله سازی اینترفیسهای سرویس و واحد کار برنامه، نمیخواهم از کتابخانه structuremap استفاده کنم . پروژه weapsy را مطالعه کردم منتها متوچه نشدم چه جایگزینی برای structuremap برگزیده است . لطفا راهنمایی بفرمایید
سپاس
و این نسبت به structuremap چگونه است ؟
An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.
context.Entry(oldEntity).CurrentValues.SetValues(newEntity)
context.Customers.MergeOption = System.Data.Objects.MergeOption.NoTracking;
context.YourEntitySet.ApplyCurrentValues(newEntity)
foreach (var item in frm.SelectedServices)
{
ObjectStateEntry temp;
if (context.ObjectStateManager.TryGetObjectStateEntry(item.Customer.EntityKey, out temp))
{
context.Detach(temp.Entity);
}
context.Services.Attach(item) ;
.
.
.
}
public class FileUpload
{
public int FileUploadId { get; set; }
public string FileName { get; set; }
}
public class Company
{
public int CompanyId { get; set; }
public string Name { get; set; }
public FileUpload Logo { get; set; }
public int? LogoId { get; set; }
public FileUpload Catalog { get; set; }
public int? CatalogId { get; set; }
}
public class Ads
{
public int AdsId { get; set; }
public string Name { get; set; }
public FileUpload Picture { get; set; }
public int? PictureId { get; set; }
}
public class TestContext : DbContext
{
public DbSet<Company> Companies { get; set; }
public DbSet<Ads> Adses { get; set; }
public DbSet<FileUpload> FileUploads { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<Ads>()
.HasOptional(a => a.Picture)
.WithMany()
.HasForeignKey(a => a.PictureId)
.WillCascadeOnDelete();
modelBuilder.Entity<Company>()
.HasOptional(a => a.Logo)
.WithMany()
.HasForeignKey(a => a.LogoId)
.WillCascadeOnDelete();
modelBuilder.Entity<Company>()
.HasOptional(a => a.Catalog)
.WithMany()
.HasForeignKey(a => a.CatalogId)
.WillCascadeOnDelete();
}
}
public class Tb1
{
public Tb1()
{
ListTb2 = new List<Tb2>();
}
public int Id { get; set; }
public string NameTb1 { get; set; }
public virtual ICollection<Tb2> ListTb2 { get; set; }
}
public class Tb2
{
public Tb2()
{
ListTb1 = new List<Tb1>();
}
public int Id { get; set; }
public string NameTb2 { get; set; }
public virtual ICollection<Tb1> ListTb1 { get; set; }
}
public class Tb1Map : EntityTypeConfiguration<Tb1>
{
public Tb1Map()
{
this.HasKey(x => x.Id);
this.HasMany(x => x.ListTb2)
.WithMany(xx => xx.ListTb1)
.Map
(
x =>
{
x.MapLeftKey("Tb1Id");
x.MapRightKey("Tb2Id");
x.ToTable("Tb1Tb2");
}
);
}
}
public class Tb2Map : EntityTypeConfiguration<Tb2>
{
public Tb2Map()
{
this.HasKey(x => x.Id);
}
}
var sv1 = new TableService<Tb1>(_uow);
var sv2 = new TableService<Tb2>(_uow);
var t1 = new Tb1 { NameTb1 = "T111" };
sv1.Add(t1);
//var res1= _uow.SaveChanges();
var t2 = new Tb2 { NameTb2 = "T222" };
sv2.Add(t2);
//var res2 = _uow.SaveChanges();
t1.ListTb2.Add(t2);
var result = _uow.SaveChanges();
An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details.
{"The INSERT statement conflicted with the FOREIGN KEY constraint \"FK_Tb1Tb2_Tb2\". The conflict occurred in database \"dbTest\", table \"dbo.Tb2\", column 'Id'.\r\nThe statement has been terminated."}
sv2.Add(t2);
t1.ListTb2.Add(t2);
namespace TestKeys
{
class Program
{
public class Bill
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public string Id { get; set; }
public decimal Amount { set; get; }
[ForeignKey("AccountId")]
public virtual Account Account { get; set; }
public string AccountId { set; get; }
}
public class Account
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public string Id { get; set; }
public string Name { get; set; }
}
public class MyContext : DbContext
{
public DbSet<Bill> Bills { get; set; }
public DbSet<Account> Accounts { get; set; }
}
public class BillFromWebsrv
{
public string Id { get; set; }
public decimal Amount { set; get; }
public DateTime DateTime { get; set; }
public Account Account { get; set; }
}
static void Main(string[] args)
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<MyContext>());
using (var ctx = new MyContext())
{
foreach (var dummyBill in DummyBills())
{
var bl = new Bill { Id = dummyBill.Id, Amount = dummyBill.Amount, Account = dummyBill.Account };
ctx.Bills.Add(bl);
}
ctx.SaveChanges();
}
}
public static List<BillFromWebsrv> DummyBills()
{
return new List<BillFromWebsrv>
{
new BillFromWebsrv
{
Id = "1",
Amount = 1231,
DateTime = DateTime.Now,
Account = new Account {Id = "1", Name = "ac1"}
},
new BillFromWebsrv
{
Id = "2",
Amount = 1232,
DateTime = DateTime.Now,
Account = new Account {Id = "2", Name = "ac2"}
},
new BillFromWebsrv
{
Id = "3",
Amount = 1233,
DateTime = DateTime.Now,
Account = new Account {Id = "2", Name = "ac2"}
},
new BillFromWebsrv
{
Id = "4",
Amount = 1134,
DateTime = DateTime.Now,
Account = new Account {Id = "3", Name = "ac3"}
}
};
}
}
} using (var ctx = new MyContext())
{
foreach (var dummyBill in DummyBills())
{
var account = dummyBill.Account;
var entry = ctx.Entry<Account>(account);
if (entry.State == EntityState.Detached)
{
var attachedEntity = ctx.Accounts.Local.SingleOrDefault(e => e.Id == account.Id);
if (attachedEntity != null)
{
// یعنی قبلا تحت نظر زمینه جاری قرار گرفته و نیازی به ثبت مجدد آن نیست
account = attachedEntity;
}
}
var bl = new Bill { Id = dummyBill.Id, Amount = dummyBill.Amount, Account = account };
ctx.Bills.Add(bl);
}
ctx.SaveChanges();
} [ForeignKey("AccountId")]
[required]
public virtual Account Account { get; set; }
public int AccountId { set; get; }