Entity Framework 6.1.2:零或一对多
Entity Framework 6.1.2: Zero or One to Many
以下代码解析 XML 并将值存储到 Entity Framework 对象中,最终在 SQL 数据库中结束:
Program.cs:
namespace locationProject
{
class Program
{
static void Main(string[] args)
{
XDocument xml = XDocument.Load("locationDoc.xml");
XNamespace cm = "http://somenamespace.com/cm";
List<Location> locationColl = new List<Location>();
List<Event> eventColl = new List<Event>();
locationModelContainer context = new locationModelContainer();
var i = 0;
var i2 = 0;
foreach (var continent in xml.Descendants(cm + "Continent"))
{
Location l = new Location();
locationColl.Add(l);
locationColl[i].Continent = (string)continent.Element(cm + "Name");
foreach (var country in continent.Elements(cm + "Country"))
{
locationColl[i].Country = (string)country.Element(cm + "Name");
foreach (var city in country.Elements(cm + "City"))
{
locationColl[i].City = (string)city.Element(cm + "Name");
context.Locations.Add(locationColl[i]);
foreach (var events in city.Elements(cm + "Event"))
{
Event e = new Event();
eventColl.Add(e);
eventColl[i2].Name = (string)events.Element(cm + "Name");
eventColl[i2].Date = (string)events.Element(cm + "Date");
context.Events.Add(eventColl[i2]);
i2++;
}
i++;
}
}
}
context.SaveChanges();
}
}
}
locationDoc.xml:
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns:cm="http://somenamespace.com/cm">
<cm:Continent>
<cm:Name>Europe</cm:Name>
<cm:Country>
<cm:Name>United Kingdom</cm:Name>
<cm:City>
<cm:Name>London</cm:Name>
<cm:Event>
<cm:Name>Event1</cm:Name>
<cm:Date>01/01/2020</cm:Date>
</cm:Event>
<cm:Event>
<cm:Name>Event2</cm:Name>
<cm:Date>01/01/2020</cm:Date>
</cm:Event>
</cm:City>
</cm:Country>
</cm:Continent>
<cm:Continent>
<cm:Name>Europe</cm:Name>
<cm:Country>
<cm:Name>France</cm:Name>
<cm:City>
<cm:Name>Paris</cm:Name>
<cm:Event>
<cm:Name>Event3</cm:Name>
<cm:Date>01/01/2020</cm:Date>
</cm:Event>
<cm:Event>
<cm:Name>Event4</cm:Name>
<cm:Date>01/01/2020</cm:Date>
</cm:Event>
</cm:City>
</cm:Country>
</cm:Continent>
<cm:Continent>
<cm:Name>Europe</cm:Name>
<cm:Country>
<cm:Name>Germany</cm:Name>
<cm:City>
<cm:Name>Berlin</cm:Name>
<cm:Event>
<cm:Name>Event5</cm:Name>
<cm:Date>01/01/2020</cm:Date>
</cm:Event>
<cm:Event>
<cm:Name>Event6</cm:Name>
<cm:Date>01/01/2020</cm:Date>
</cm:Event>
</cm:City>
</cm:Country>
</cm:Continent>
</feed>
Location.cs:
namespace locationProject
{
using System;
using System.Collections.Generic;
public partial class Location
{
public Location()
{
this.Events = new HashSet<Event>();
}
public int LocationID { get; set; }
public string Continent { get; set; }
public string Country { get; set; }
public string City { get; set; }
public virtual ICollection<Event> Events { get; set; }
}
}
Event.cs:
namespace locationProject
{
using System;
using System.Collections.Generic;
public partial class Event
{
public int EventID { get; set; }
public Nullable<int> Location_LocationID { get; set; }
public string Name { get; set; }
public string Date { get; set; }
public virtual Location Location { get; set; }
}
}
locationModelContainer:
public partial class locationModelContainer : DbContext
{
public locationModelContainer()
: base("name=locationModelContainer")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<Location> Locations { get; set; }
public virtual DbSet<Event> Events { get; set; }
}
}
locationModel.edmx.sql:
SET QUOTED_IDENTIFIER OFF;
GO
USE [Locations];
GO
IF SCHEMA_ID(N'dbo') IS NULL EXECUTE(N'CREATE SCHEMA [dbo]');
GO
IF OBJECT_ID(N'[dbo].[FK_LocationEvent]', 'F') IS NOT NULL
ALTER TABLE [dbo].[Events] DROP CONSTRAINT [FK_LocationEvent];
GO
IF OBJECT_ID(N'[dbo].[Locations]', 'U') IS NOT NULL
DROP TABLE [dbo].[Locations];
GO
IF OBJECT_ID(N'[dbo].[Events]', 'U') IS NOT NULL
DROP TABLE [dbo].[Events];
GO
CREATE TABLE [dbo].[Locations] (
[LocationID] int IDENTITY(1,1) NOT NULL,
[Continent] nvarchar(max) NOT NULL,
[Country] nvarchar(max) NOT NULL,
[City] nvarchar(max) NOT NULL
);
GO
CREATE TABLE [dbo].[Events] (
[EventID] int IDENTITY(1,1) NOT NULL,
[Location_LocationID] int NULL,
[Name] nvarchar(max) NOT NULL,
[Date] nvarchar(max) NOT NULL
);
GO
ALTER TABLE [dbo].[Locations]
ADD CONSTRAINT [PK_Locations]
PRIMARY KEY CLUSTERED ([LocationID] ASC);
GO
ALTER TABLE [dbo].[Events]
ADD CONSTRAINT [PK_Events]
PRIMARY KEY CLUSTERED ([EventID] ASC);
GO
ALTER TABLE [dbo].[Events]
ADD CONSTRAINT [FK_LocationEvent]
FOREIGN KEY ([Location_LocationID])
REFERENCES [dbo].[Locations]
([LocationID])
ON DELETE NO ACTION ON UPDATE NO ACTION;
GO
CREATE INDEX [IX_FK_LocationEvent]
ON [dbo].[Events]
([Location_LocationID]);
GO
使用一对多关系(一个位置到多个事件)按预期工作。 Location_LocationID
外键被相关的 LocationID
填充。
尽管如此,如上代码所示,我的预期设计是使用零或一对多关系(零或一个位置到多个事件)。但是,使用此关系不会填充 Location_LocationID
外键,而是在保存到数据库时,所有 Location_LocationID
字段都包含 NULL
。
谁能解释一下为什么他们没有使用这种关系填充?提前致谢!
您目前没有为任何活动设置地点。所以它当然总是空的。您也只是在每个大陆创建一个位置。将创建位置的位置移动到枚举城市的位置。
foreach (var continent in xml.Descendants(cm + "Continent"))
{
var continent = (string)continent.Element(cm + "Name");
foreach (var country in continent.Elements(cm + "Country"))
{
var country = (string)country.Element(cm + "Name");
foreach (var city in country.Elements(cm + "City"))
{
Location l = new Location();
l.Continent = continent;
l.Country = country;
l.City = (string)city.Element(cm + "Name");
context.Locations.Add(l);
locationColl.Add(l);
foreach (var events in city.Elements(cm + "Event"))
{
Event e = new Event();
eventColl.Add(e);
e.Location = l;
eventColl[i2].Name = (string)events.Element(cm + "Name");
eventColl[i2].Date = (string)events.Element(cm + "Date");
context.Events.Add(eventColl[i2]);
i2++;
}
i++;
}
}
}
context.SaveChanges();
以下代码解析 XML 并将值存储到 Entity Framework 对象中,最终在 SQL 数据库中结束:
Program.cs:
namespace locationProject
{
class Program
{
static void Main(string[] args)
{
XDocument xml = XDocument.Load("locationDoc.xml");
XNamespace cm = "http://somenamespace.com/cm";
List<Location> locationColl = new List<Location>();
List<Event> eventColl = new List<Event>();
locationModelContainer context = new locationModelContainer();
var i = 0;
var i2 = 0;
foreach (var continent in xml.Descendants(cm + "Continent"))
{
Location l = new Location();
locationColl.Add(l);
locationColl[i].Continent = (string)continent.Element(cm + "Name");
foreach (var country in continent.Elements(cm + "Country"))
{
locationColl[i].Country = (string)country.Element(cm + "Name");
foreach (var city in country.Elements(cm + "City"))
{
locationColl[i].City = (string)city.Element(cm + "Name");
context.Locations.Add(locationColl[i]);
foreach (var events in city.Elements(cm + "Event"))
{
Event e = new Event();
eventColl.Add(e);
eventColl[i2].Name = (string)events.Element(cm + "Name");
eventColl[i2].Date = (string)events.Element(cm + "Date");
context.Events.Add(eventColl[i2]);
i2++;
}
i++;
}
}
}
context.SaveChanges();
}
}
}
locationDoc.xml:
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns:cm="http://somenamespace.com/cm">
<cm:Continent>
<cm:Name>Europe</cm:Name>
<cm:Country>
<cm:Name>United Kingdom</cm:Name>
<cm:City>
<cm:Name>London</cm:Name>
<cm:Event>
<cm:Name>Event1</cm:Name>
<cm:Date>01/01/2020</cm:Date>
</cm:Event>
<cm:Event>
<cm:Name>Event2</cm:Name>
<cm:Date>01/01/2020</cm:Date>
</cm:Event>
</cm:City>
</cm:Country>
</cm:Continent>
<cm:Continent>
<cm:Name>Europe</cm:Name>
<cm:Country>
<cm:Name>France</cm:Name>
<cm:City>
<cm:Name>Paris</cm:Name>
<cm:Event>
<cm:Name>Event3</cm:Name>
<cm:Date>01/01/2020</cm:Date>
</cm:Event>
<cm:Event>
<cm:Name>Event4</cm:Name>
<cm:Date>01/01/2020</cm:Date>
</cm:Event>
</cm:City>
</cm:Country>
</cm:Continent>
<cm:Continent>
<cm:Name>Europe</cm:Name>
<cm:Country>
<cm:Name>Germany</cm:Name>
<cm:City>
<cm:Name>Berlin</cm:Name>
<cm:Event>
<cm:Name>Event5</cm:Name>
<cm:Date>01/01/2020</cm:Date>
</cm:Event>
<cm:Event>
<cm:Name>Event6</cm:Name>
<cm:Date>01/01/2020</cm:Date>
</cm:Event>
</cm:City>
</cm:Country>
</cm:Continent>
</feed>
Location.cs:
namespace locationProject
{
using System;
using System.Collections.Generic;
public partial class Location
{
public Location()
{
this.Events = new HashSet<Event>();
}
public int LocationID { get; set; }
public string Continent { get; set; }
public string Country { get; set; }
public string City { get; set; }
public virtual ICollection<Event> Events { get; set; }
}
}
Event.cs:
namespace locationProject
{
using System;
using System.Collections.Generic;
public partial class Event
{
public int EventID { get; set; }
public Nullable<int> Location_LocationID { get; set; }
public string Name { get; set; }
public string Date { get; set; }
public virtual Location Location { get; set; }
}
}
locationModelContainer:
public partial class locationModelContainer : DbContext
{
public locationModelContainer()
: base("name=locationModelContainer")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<Location> Locations { get; set; }
public virtual DbSet<Event> Events { get; set; }
}
}
locationModel.edmx.sql:
SET QUOTED_IDENTIFIER OFF;
GO
USE [Locations];
GO
IF SCHEMA_ID(N'dbo') IS NULL EXECUTE(N'CREATE SCHEMA [dbo]');
GO
IF OBJECT_ID(N'[dbo].[FK_LocationEvent]', 'F') IS NOT NULL
ALTER TABLE [dbo].[Events] DROP CONSTRAINT [FK_LocationEvent];
GO
IF OBJECT_ID(N'[dbo].[Locations]', 'U') IS NOT NULL
DROP TABLE [dbo].[Locations];
GO
IF OBJECT_ID(N'[dbo].[Events]', 'U') IS NOT NULL
DROP TABLE [dbo].[Events];
GO
CREATE TABLE [dbo].[Locations] (
[LocationID] int IDENTITY(1,1) NOT NULL,
[Continent] nvarchar(max) NOT NULL,
[Country] nvarchar(max) NOT NULL,
[City] nvarchar(max) NOT NULL
);
GO
CREATE TABLE [dbo].[Events] (
[EventID] int IDENTITY(1,1) NOT NULL,
[Location_LocationID] int NULL,
[Name] nvarchar(max) NOT NULL,
[Date] nvarchar(max) NOT NULL
);
GO
ALTER TABLE [dbo].[Locations]
ADD CONSTRAINT [PK_Locations]
PRIMARY KEY CLUSTERED ([LocationID] ASC);
GO
ALTER TABLE [dbo].[Events]
ADD CONSTRAINT [PK_Events]
PRIMARY KEY CLUSTERED ([EventID] ASC);
GO
ALTER TABLE [dbo].[Events]
ADD CONSTRAINT [FK_LocationEvent]
FOREIGN KEY ([Location_LocationID])
REFERENCES [dbo].[Locations]
([LocationID])
ON DELETE NO ACTION ON UPDATE NO ACTION;
GO
CREATE INDEX [IX_FK_LocationEvent]
ON [dbo].[Events]
([Location_LocationID]);
GO
使用一对多关系(一个位置到多个事件)按预期工作。 Location_LocationID
外键被相关的 LocationID
填充。
尽管如此,如上代码所示,我的预期设计是使用零或一对多关系(零或一个位置到多个事件)。但是,使用此关系不会填充 Location_LocationID
外键,而是在保存到数据库时,所有 Location_LocationID
字段都包含 NULL
。
谁能解释一下为什么他们没有使用这种关系填充?提前致谢!
您目前没有为任何活动设置地点。所以它当然总是空的。您也只是在每个大陆创建一个位置。将创建位置的位置移动到枚举城市的位置。
foreach (var continent in xml.Descendants(cm + "Continent"))
{
var continent = (string)continent.Element(cm + "Name");
foreach (var country in continent.Elements(cm + "Country"))
{
var country = (string)country.Element(cm + "Name");
foreach (var city in country.Elements(cm + "City"))
{
Location l = new Location();
l.Continent = continent;
l.Country = country;
l.City = (string)city.Element(cm + "Name");
context.Locations.Add(l);
locationColl.Add(l);
foreach (var events in city.Elements(cm + "Event"))
{
Event e = new Event();
eventColl.Add(e);
e.Location = l;
eventColl[i2].Name = (string)events.Element(cm + "Name");
eventColl[i2].Date = (string)events.Element(cm + "Date");
context.Events.Add(eventColl[i2]);
i2++;
}
i++;
}
}
}
context.SaveChanges();