[英]Configuring many One-To-One relationships with Entity Framework Code First and Fluent API
I have a horrible database model (in MySQL though I don't think that matters) that someone else designed so I'm stuck with it, but want to use with Entity Framework with it anyway: 我有一个别人设计的可怕的数据库模型(在MySQL中,尽管我认为这并不重要),所以我坚持使用它,但是无论如何都想与Entity Framework一起使用:
Item 项目
ASSET_ID* ASSET_NAME FIELDS_ID
1 Cat 1
2 Dog 2
3 Fish 3
ItemFields ItemFields
ID* CUSTOMFIELD1ID CUSTOMFIELD2ID CUSTOMFIELD3ID
1 1001 1002 1003
2 1004 1005 1006
3 1007 1008 1009
Field 领域
ID* STRINGVAL
1001 Meow Mix
1002 House
1003 5lbs
1004 Kibble
1005 Yard
1006 30lbs
1007 Fish Food
1008 Tank
1009 0.5 ounces
*indicates table's PK *表示表的PK
Ultimately, I'm trying to configure the relationships so I can get custom data like this: 最终,我试图配置这些关系,以便我可以像这样获得自定义数据:
Item item = GetItem(1);
item.Food.ToString(); // Output: meow mix
item.Place.ToString(); // Output: house
item.Weight.ToString(); // Output: 5 lbs
...etc. ...等等。 but honestly I'd settle for this at this point: 但老实说,我现在已经满足了:
Item item = GetItem(1);
Item.ItemFields.CustomField3.Value // Output: 5 lbs
Item item = GetItem(2);
Item.ItemFields.CustomField2.Value // Output: Yard
Item item = GetItem(3);
Item.ItemFields.CustomField1.Value // Output: Fish Food
So far I've got this: 到目前为止,我已经知道了:
One-To-One: Item - ItemFields 一对一:项目-ItemFields
modelBuilder.Entity<Item>()
.HasRequired(x => x.ItemFields)
.WithRequiredPrincipal(y => y.Item);
But what about mapping ItemFields.CustomField1ID to Field.ID? 但是,如何将ItemFields.CustomField1ID映射到Field.ID?
Is it even possible to configure a relationship like this using EF code first? 甚至有可能首先使用EF代码配置这样的关系? I'm pretty confused about whether or not this is a one-to-one or a one-to-many... I think what it actually is is many one-to-ones (if that makes sense). 对于这是一对一还是一对多,我感到很困惑。我认为实际上是许多一对一的关系(如果这样的话)。
Any suggestions? 有什么建议么?
I may have figured this out. 我可能已经知道了。 I edited my ItemFields class to look like this: 我编辑了ItemFields类,使其看起来像这样:
public class ItemFields
{
public int Id { get; set; }
public int CUSTOMFIELD1ID { get; set; }
public virtual Field CustomField1 { get; set; }
And then configured these relationships: 然后配置这些关系:
modelBuilder.Entity<Item>()
.HasRequired(x => x.CustomField1)
.WithMany()
.HasForeignKey(x => x.CUSTOMFIELD01_ID);
modelBuilder.Entity<Item>()
.HasRequired(x => x.CustomField2)
.WithMany()
.HasForeignKey(x => x.CUSTOMFIELD02_ID);
And it seems to have worked, though to be honest I don't fully understand why. 它似乎奏效了,尽管说实话我不完全理解为什么。 I'd still ideally like to map them to more user-friendly classes. 理想情况下,我仍然希望将它们映射到更用户友好的类。
I think you agree that at this case we actually have one-to-many relationship: one item has several fields and table ItemFields is surrogate thing. 我认为您同意在这种情况下我们实际上是一对多的关系:一项具有多个字段,表ItemFields是替代项。 I recommend you to perform refactoring and create only two tables: Items and Fields. 我建议您执行重构并仅创建两个表:项目和字段。 In Fields table will be added column Type - similar CUSTOMFIELD1ID(2ID,3ID) and foreign key referenced directly to Items table. 在字段表中将添加列类型-类似的CUSTOMFIELD1ID(2ID,3ID)和直接引用到Items表的外键。 In Item class were added properties: Food, Place and Weight. 在项目类中添加了属性:食物,位置和重量。 They will not be mapped to columns, but you can use them as you specified in your question for accessing to particular fields(look at IMPLEMENTATION section): 它们不会被映射到列,但是您可以按照在问题中指定的方式使用它们来访问特定字段(请参见IMPLEMENTATION部分):
MODELS: 楷模:
public enum CustomType
{
Food,
Place,
Weight
}
public class Item
{
public int ID { get; set; }
public string ASSET_NAME { get; set; }
public virtual ICollection<Field> fields { get; set; }
[NotMapped]
public Field Food { get { return fields == null ? null : fields.Where(x => x.Type == CustomType.Food).FirstOrDefault(); } }
[NotMapped]
public Field Place { get { return fields == null ? null : fields.Where(x => x.Type == CustomType.Place).FirstOrDefault(); } }
[NotMapped]
public Field Weight { get { return fields == null ? null : fields.Where(x => x.Type == CustomType.Weight).FirstOrDefault(); } }
}
public class Field
{
public int ID { get; set; }
public string STRINGVAL { get; set; }
public CustomType Type { get; set; }
public virtual Item Item { get; set; }
}
TABLES: 表:
var db = new DataContext();
var item = db.Items.Include("fields").Where(x => x.ID == 1).First();
var Food = item.Food;
var Place = item.Place;
var Weight = item.Weight;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.