我有两张表order_lines
和[Table("order")]
public class order : BaseModel
{
public order()
{
this.OrderLines = new List<order_lines>();
}
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int id { get; set; }
public double? total { get; set; }
public List<order_lines> OrderLines { get; set; }
}
[Table("order_lines")]
public class order_lines : BaseModel
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int id { get; set; }
public int? ordernum { get; set; }
[MaxLength(1000)]
public string sku { get; set; }
[ForeignKey("id")]
public order Order { get; set; }
}
。他们都有主/外键关系。但是,当我尝试检索数据时,我没有看到来自我的导航属性的任何数据。
OrderLines
我正在使用下面显示的Linq查询来获取数据。我希望看到var data = (from o in Context.order
select o).ToList();
属性已填充,但它返回0计数。
string fileExtension = "*.zip";//file type
string[] txtFiles = Directory.GetFiles(sourcePath, fileExtension);//find all zip files
foreach (var item in txtFiles)//move all zip files
{
if (File.Exists(item)
{
File.Move(source, destination + item.GetFileName(source));//move the file into destination
}
else
{
File.Move(source, destination2 + item.GetFileName(source));//move the file into destination
}
}
答案 0 :(得分:3)
问题的原因是您忘记为外键定义属性。由于外键属性,我猜它会在你的order_lines表中。
我注意到你偏离了the entity framework code first conventions。这有充分的理由吗?这些偏差会使您的代码变得更大,更难以理解,更难以维护,并且如果被其他人更改则更容易出错。
主要的偏差是您省略了外键的属性。另一个原因是您将一对多关系定义为List<order_lines]
而不是ICollection<order_lines]
。您确定MyOrder.Order_Lines[4]
具有明确的含义吗?
此外,您确定查询结果是真实的列表吗?可能是内部数据库查询会返回类似于List的东西,但实际上是其他东西,例如数组?您真的想将自己和代码用户限制为List吗?
此外,您的一对多引用OrderLines
和Order
未声明为虚拟。它们不会是表格中的列。
最后,您不会遵循自己的命名约定,也不会遵循C#常用的约定。类order_lines
具有复数标识符,类order
具有单数标识符。 order_lines
是小写字母,而您对order_lines
集合的引用始于首都。除OrderLines
突然没有下划线
虽然这是允许的,并且您的编译器不会抱怨,但这些偏差需要多个属性或流畅的API才能使其工作。除此之外,如果其他人更难以阅读您的代码并理解您的表之间的关系。
所以我的建议是:坚持惯例,只有你真的需要偏离。不是因为'你忘了'。
如果遵守约定,则不需要使用大量代码和大多数属性。
class Order : BaseModel
{
public int Id { get; set; }
// every Order has zero or more OrderLines
public virtual ICollection <OrderLines> OrderLines { get; set; }
public double? Total { get; set; }
}
public class OrderLines : BaseModel
{
public int id { get; set; }
// every OrderLine belongs to exactly one Order, using foreign key
public int OrderId {get; set;}
public virtual Order Order { get; set; }
public int? Ordernum { get; set; }
[MaxLength(1000)]
public string Sku { get; set; }
}
因为我坚持惯例,所以实体框架需要理解你的一对多关系。它知道哪些属性是您的主键,哪些是外键。剩下的唯一属性是Sku的最大长度
请注意,我将您的列表更改为ICollection。此外,我删除了构造函数。在查询中,构造函数将创建一个列表,该列表将立即被查询的结果替换:多么浪费!
最后,我使用了正确的名称标识符。
使用多个OrderLines引入新订单将按如下方式进行:
var addedOrder = myDbContext.Orders.Add(new Order()
{
Total = calculatedTotal, // or null
OrderLines = new OrderLines[]
{
new OrderLine() {Sku = ...; ...},
new OrderLine() {Sku = ...; ...},
new OrderLine() {Sku = ...; ...},
},
});
请注意,在此示例中,我创建了array
OrderLines
。我定义了一个ICollection。因此,我也可以使用ListOrderLine>
或(让我们疯狂)使用某个查询的Dictionary<int, OrderLine>
或ToList()
的值。
我也可以像这样添加OrderLines:
var addedOrder = myDbContext.Orders.Add(new Order()
{
OrderLines = new List<OrderLine>(),
});
addedOrder.OrderLines.Add(new OrderLine() {...};
或者:
var addedOrder = myDbContext.OrderLines.Add(new OrderLine()
{
Order = addedOrder,
...
});
所有这一切都成为可能,因为Orders和OrderLines之间的引用被声明为虚拟和ICollection。
答案 1 :(得分:0)
你为你的PK设置了外键。我认为它应该是“orderId”而不是“id”。
[ForeignKey("orderId")] // Select you column with you FKey
public order Order { get; set; }
您的列表需要引用该属性。添加attribute
[InverseProperty("Order")]
并将类型更改为ICollection:
[InverseProperty("Order")] // Select the property-name of the Other class
public ICollection<order_lines> OrderLines { get; set; }
答案 2 :(得分:0)
如果您没有使用标准命名约定,那么您必须在上下文中执行以下操作来解决此问题。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Orders>()
.HasKey(e => e.CaregiverCode)
.HasMany(e => e.OrderLines)
.WithOptional(e => e.Orders)
.HasForeignKey(e => e.ordernum);
}