C# 在数据库中复制的实体框架对象
我第一次使用实体框架(代码优先),我有一个小问题 我有一门课叫出租车,一门课叫司机 出租车有一个参考司机,你可以看到下面两个等级C# 在数据库中复制的实体框架对象,c#,entity-framework,C#,Entity Framework,我第一次使用实体框架(代码优先),我有一个小问题 我有一门课叫出租车,一门课叫司机 出租车有一个参考司机,你可以看到下面两个等级 public partial class Taxi { public Taxi() { } public int TaxiId { get; set; } public Driver Driver { get; set; } public string Mak
public partial class Taxi
{
public Taxi()
{
}
public int TaxiId { get; set; }
public Driver Driver { get; set; }
public string Make { get; set; }
public string Model { get; set; }
public Color Colour { get; set; }
public string NumPlate { get; set; }
public int MaxPassengers { get; set; }
}
public partial class Driver
{
public Driver()
{
}
public int DriverId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public string HomePhone { get; set; }
public string MobilePhone { get; set; }
public DateTime JoinedFirm { get; set; }
}
我这样保存换好的出租车:
using (var db = new DataModel())
{
db.Configuration.ProxyCreationEnabled = false;
db.Taxis
.Where(x => x.TaxiId == CurrenltySelectedTaxi.TaxiId)
.ToList()
.ForEach(x =>
{
x.Make = CurrenltySelectedTaxi.Make;
x.Model = CurrenltySelectedTaxi.Model;
x.NumPlate = CurrenltySelectedTaxi.NumPlate;
x.Colour = CurrenltySelectedTaxi.Colour;
x.MaxPassengers = CurrenltySelectedTaxi.MaxPassengers;
x.Driver = CurrenltySelectedTaxi.Driver;
});
db.SaveChanges();
}
listDrivers.Items.AddRange(db.Drivers.ToArray());
public partial class Taxi
{
public Taxi()
{
}
public int TaxiId { get; set; }
public int DriverId {get; set; }
public virtual Driver Driver { get; set; }
public string Make { get; set; }
public string Model { get; set; }
public Color Colour { get; set; }
public string NumPlate { get; set; }
public int MaxPassengers { get; set; }
}
我的问题是,每次我保存出租车时,数据库中的司机都会被复制
您可以在此处看到数据库:
有人能给我指出正确的方向吗,
谢谢
编辑:
驱动程序在一个组合框中,按如下方式选择
private void cmbTaxiDriver_SelectedIndexChanged(object sender, EventArgs e)
{
using (var db = new DataModel())
{
db.Configuration.ProxyCreationEnabled = false;
Driver listSelected = (Driver) cmbTaxiDriver.SelectedItem;
CurrenltySelectedTaxi.Driver = db.Drivers.Where(x => x.DriverId == listSelected.DriverId).ToArray()[0];
}
}
组合框的填充方式如下:
using (var db = new DataModel())
{
db.Configuration.ProxyCreationEnabled = false;
db.Taxis
.Where(x => x.TaxiId == CurrenltySelectedTaxi.TaxiId)
.ToList()
.ForEach(x =>
{
x.Make = CurrenltySelectedTaxi.Make;
x.Model = CurrenltySelectedTaxi.Model;
x.NumPlate = CurrenltySelectedTaxi.NumPlate;
x.Colour = CurrenltySelectedTaxi.Colour;
x.MaxPassengers = CurrenltySelectedTaxi.MaxPassengers;
x.Driver = CurrenltySelectedTaxi.Driver;
});
db.SaveChanges();
}
listDrivers.Items.AddRange(db.Drivers.ToArray());
public partial class Taxi
{
public Taxi()
{
}
public int TaxiId { get; set; }
public int DriverId {get; set; }
public virtual Driver Driver { get; set; }
public string Make { get; set; }
public string Model { get; set; }
public Color Colour { get; set; }
public string NumPlate { get; set; }
public int MaxPassengers { get; set; }
}
根据您提供的内容,我唯一能找到的是
CurrenltySelectedTaxi.Driver
是一个分离的或新的驱动程序。小心确保当前选定的驱动程序所指向的对象是附加的驱动程序记录
可以帮助确定该记录状态的一个选项是在该行上放置一个断点,然后查看DbEntry记录状态。您的设计不会在出租车和司机之间创建将转换为数据库的关系。试着这样做:
using (var db = new DataModel())
{
db.Configuration.ProxyCreationEnabled = false;
db.Taxis
.Where(x => x.TaxiId == CurrenltySelectedTaxi.TaxiId)
.ToList()
.ForEach(x =>
{
x.Make = CurrenltySelectedTaxi.Make;
x.Model = CurrenltySelectedTaxi.Model;
x.NumPlate = CurrenltySelectedTaxi.NumPlate;
x.Colour = CurrenltySelectedTaxi.Colour;
x.MaxPassengers = CurrenltySelectedTaxi.MaxPassengers;
x.Driver = CurrenltySelectedTaxi.Driver;
});
db.SaveChanges();
}
listDrivers.Items.AddRange(db.Drivers.ToArray());
public partial class Taxi
{
public Taxi()
{
}
public int TaxiId { get; set; }
public int DriverId {get; set; }
public virtual Driver Driver { get; set; }
public string Make { get; set; }
public string Model { get; set; }
public Color Colour { get; set; }
public string NumPlate { get; set; }
public int MaxPassengers { get; set; }
}
您可能还希望将以下内容添加到驱动程序对象:
public virtual IEnumerable<Taxi> Taxis { get; set; }
公共虚拟IEnumerable出租车{get;set;}
所以我的问题是因为我遵循了MSDN的教程,其中说每次使用时都要重新创建上下文。虽然这“可能”是一个好的做法,但在这种情况下,它导致了问题
如果我为整个类创建了一个上下文,它将按预期工作/请包含其他代码,例如如何选择
CurrenltySelectedTaxi
。此外,我将假设在db.Taxis
中应该只有一个taxid
实例,如果这是真的,那么首先执行db.Taxis(x=>x.taxid==CurrenltySelectedTaxi.TaxiId)
然后分配属性。(假设出租车id已经存在,如果可能不存在,请使用first或default)添加了如何选择驱动程序。CurrentlySelectedTaxi is select与从另一个位置选择的方式相同。可能是您的事件SelectIndexChanged
被调用了两次吗?如果调用了两次,则不会有什么区别,因为它不会更改数据库。如何选中此项?我会像“listDrivers”这样填充组合框。它ems.AddRange(db.Drivers.ToArray());`并像`使用(var db=new DataModel()){db.Configuration.ProxyCreationEnabled=false;Driver list selected=(Driver)cmbTaxiDriver.SelectedItem;CurrenltySelectedTaxi.Driver=db.Drivers.Where(x=>x.DriverId==listSelected.DriverId)那样选择它.ToArray()[0];}`不要将整个记录添加到列表中,而是依赖于ToString()命令…另外…不要将数据库上下文保留很长时间…只在处理事务时实例化数据库内容。否则,请加载带有ID和标题的列表/组合框…将x.Driver直接分配给DbSet中的对象…或停止使用navigation属性,改为分配DriverID列。这就是我所做的最初,我删除了它,因为使用公共虚拟驱动程序驱动程序{get;set;}再次测试了这个问题。在db.SaveChanges()将其更改为列表中的下一个(在本例中为10,下一个测试11)之后,我逐步执行并将DriverID=2。您是否仍在为驱动程序属性设置值?因为这不必要(甚至可能是问题所在)-重要的是将DriverId属性设置为正确的值它在该函数中发生了更改,所以不要设置Driver属性。只设置DriverId。或者,如果您确实必须设置Driver属性,请确保将其标记为正在更新,因为听起来EF默认为它是一个新对象。是的,但这会使与数据库的连接处于打开状态,从而引入其他可能的问题。y是什么您要做的是,通过为实体设置适当的状态,确保您的上下文知道如何处理您提供给它的项: