我有两个这样的课程:
public class Event
{
[Key]
[Required]
public long Id { get; set; }
[InverseProperty("Event")
public virtual Record Record{ get; set; }
}
public class Record
{
[Key]
[Required]
public int Id { get; set; }
[ForeignKey("Event")]
public long? EventId { get; set; }
public virtual Event Event{ get; set; }
}
但是,通过此设置我得到了预期的多重性错误。我要结束的是:
没有记录的现有事件
记录现有事件而没有事件
与记录一起存在的事件(并在记录中存储事件ID)
有可能吗?我必须使用FluentApi
而不是Data Annotations
吗?
我不想在“事件”表中添加任何字段或键。
答案 0 :(得分:1)
在EF 6.x中,您必须使用Fluent API进行如下配置:
import React, { Component } from 'react';
import { fade } from '@material-ui/core/styles/colorManipulator';
import { withStyles } from '@material-ui/core/styles';
import { connect } from 'react-redux';
import AuthA from '../store/actions/AuthA';
import { withRouter } from 'react-router-dom';
import '../Navbar.css';
import NavbarV from './NavbarV';
import PropTypes from 'prop-types';
import axios from 'axios';
class NavbarC extends Component {
constructor(props){
super(props);
this.state = {
client:[]
}
}
componentWillMount(){
this.getUser();
}
getUser(){
axios.get (`http://localhost:3002/api/clients/${localStorage.getItem("userId")}?access_token=${localStorage.getItem("token")}`)
.then(res => {
this.setState({client: res.data}, () => {
console.log(this.state)
})
})
}
shouldComponentUpdate(nextState){
return (this.state.client.firstName !== nextState.firstName ||
this.state.client.lastName !== nextState.lastName);
}
componentWillUpdate(){
this.getUser();
console.log(this.state)
}
logout = () => {
this.props.authfn.logout();
};
render() {
return(
<NavbarV logout = {this.logout}
firstName={this.state.client.firstName}
lastName={this.state.client.lastName}
userId={this.props.userId}
auth = {this.props.auth}
classes={this.props.classes}/>
)
}
}
NavbarC.propTypes = {
auth: PropTypes.bool.isRequired,
firstName: PropTypes.string.isRequired,
lastName: PropTypes.string.isRequired
};
const mapStateToProps = (state) => {
return {
auth: state.AuthR.auth,
firstName: state.AuthR.firstName,
lastName: state.AuthR.lastName,
userId: state.AuthR.userId
};
};
const mapDispatchToProps = dispatch => {
return {
authfn: AuthA(dispatch)
}
};
export default connect(mapStateToProps, mapDispatchToProps) (withStyles(styles)(withRouter(NavbarC)));
在EF Core中,您当前的模型设置已经足够好!不需要做任何其他事情。
答案 1 :(得分:1)
您是正确的,仅给关系的两侧之一提供了外键。我首先认为双方都需要一个可为空的外键。但是,如果您愿意这样做,则事件1可能具有记录2的外键,而事件3则具有记录4的外键,等等。
显然,在这些情况下,两侧中只有一个具有外键。
看着configure one-to-zero-or-one relation,我发现以下内容就足够了:
class Event
{
public long Id { get; set; }
public string Name { get; set; }
// Every Event has zero or one Record
public virtual Record Record { get; set; }
}
class Record
{
public long Id { get; set; }
public string Name { get; set; }
// Every Record has zero or one Event
public virtual Event Event { get; set; }
}
和DbContext:
class OneToOneContext : DbContext
{
public OneToOneContext(): base("OneToOneDemo"){}
public DbSet<Event> Events { get; set; }
public DbSet<Record> Records { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Record>()
.HasOptional(record => record.Event)
.WithOptionalDependent(ev => ev.Record)
.WillCascadeOnDelete(false);
}
}
流利的API通知模型构建者每个记录都有零个或一个事件,零个或一个记录。记录被声明为依赖。这样可以确保Record在此关系中具有异国情调。
请注意,我不必添加任何其他属性。因为我遵循code first conventions实体框架,所以能够检测到主键和表之间的关系。
我能够添加:不带记录的事件,不带事件的记录,带记录的事件和带事件的记录:
using (var dbContext = new OneToOneContext())
{
dbContext.Events.Add(new Event { Name = "Event without Record"});
dbContext.Records.Add(new Record { Name = "Record without Event" });
dbContext.Events.Add(new Event
{
Name = "Event A with Record",
Record = new Record { Name = "Record of Event A" },
});
dbContext.Records.Add(new Record
{
Name = "Record B with Event",
Event = new Event { Name = "Event of Record B" },
});
dbContext.SaveChanges();
}