Saturday 28 April 2018

jquery side nav menu

menu 1
sub 1
sub 2
menu 2
sub 1
sub 2
menu 3
sub 1
sub 2

Sidenav Push Example

Click on the element below to open the side navigation menu, and push this content to the right.
☰ close




<style>

.side_nav_left{

    height:400px;

    width:200px;

    background-color:black;

    color:white;

    transition:0.5s;

    overflow-x:hidden;

    position:absolute;

}



.open_nav{

    font-size:30px;

    cursor:pointer;

}



#top_container {

    margin-left: 200px;

    transition:0.5s;

}



.side_nav_menu{

    /*height:50px;*/

    width:100%;

    font-size:30px;

    text-align:center;

    transition:0.5s;

    cursor:pointer;

}



.side_nav_submenu{

    height:30px;

    width:100%;

    font-size:20px;

    text-align:center;

    display:none;

}

</style>



<head>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

</head>



<body>



<div class="side_nav_left" id="side_nav">



        <div class="side_nav_menu" onclick="toggle_submenu()">

            menu 1

            <div class="side_nav_submenu">
sub 1</div>
<div class="side_nav_submenu">
sub 2</div>
</div>
<div class="side_nav_menu" onclick="toggle_submenu()">

            menu 2

            <div class="side_nav_submenu">
sub 1</div>
<div class="side_nav_submenu">
sub 2</div>
</div>
<div class="side_nav_menu" onclick="toggle_submenu()">

            menu 3

            <div class="side_nav_submenu">
sub 1</div>
<div class="side_nav_submenu">
sub 2</div>
</div>
</div>
<div id="top_container">

        <h2>
Sidenav Push Example</h2>
Click on the element below to open the side navigation menu, and push this content to the right.<br />


        <span class="open_nav" id="sandwich_bar" onclick="toggleNav()">☰ close</span>

    </div>
<script>

var open = true;



        function toggleNav() {

            if (open) {

                open = false;

                $(".side_nav_left").css("width", 0);

                $(".side_nav_menu").css("display", "none");

                $("#top_container").css("margin-left", 0);

                $("#sandwich_bar").html("&#9776; open");

            }

            else {

                open = true

                $(".side_nav_left").css("width", "200px");

                $(".side_nav_menu").css("display", "block");

                $("#top_container").css("margin-left", "200px");

                $("#sandwich_bar").html("&#9776; close");

            }

        }



        function toggle_submenu() {

            $(".side_nav_submenu").slideToggle("slow");

        }

</script>

Friday 27 April 2018

javascript callback

start task


A callback function is a function passed into another function as an argument, which is then invoked inside the outer function to complete some kind of routine or action.

<div class="show_visitor" onclick="task1(task2)">start task</div>

<script>

function task4(pre_task){
  alert('previous task: '+ pre_task+' current task 4');
}

function task3(pre_task, callback){
  alert('previous task: '+ pre_task+' current task 3');
  callback('task3');
}

function task2(pre_task,callback) {
  alert('previous task: '+ pre_task+' current task: task 2');
  callback('task 2',task4);
}

function task1(callback) {
  alert('current task 1');
  callback('task 1',task3);
}

reference:
https://codeburst.io/javascript-what-the-heck-is-a-callback-aba4da2deced
https://developer.mozilla.org/en-US/docs/Glossary/Callback_function

Friday 20 April 2018

ajax cors



reference:
https://gist.github.com/rememberlenny/9de4fdeb5c487ba020fb

cors.io
https://cors.io/

AJAX Tester
http://igem.org/AJAX_Tester

Locate Online Visitors


show my ip location

<style>

#visitor_ip{

color:cyan;

}

#my_map {
    height: 400px;
    width: 100%;
}

.show_visitor{

display:block;

height:20px;
width:150px;
cursor:pointer;
background-color:green;
border-style: dotted;
border-color:red;
border-width:1px;
border-radius: 5px;
box-shadow: 0 3px #999;
}

.show_visitor:active{
box-shadow: 0 5px #666;
transform: translateY(2px);
}

</style>

<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script async defer
            src="https://maps.googleapis.com/maps/api/js?key=AIzaSyA3vsA_vWUSgzSc8e5vzfmLEqdYwuL86Qg&callback=initMap">
    </script>
</head>



<br />

<div class="show_visitor" onclick="show_visitor_address()">show my ip location</div>
<div id="my_map"></div>
<div id="visitor_ip">

</div>

<script>

function show_visitor_address(){

$.getJSON('https://ipapi.co/json/', function(data) {

  $("#visitor_ip").html(JSON.stringify(data, null, 2).replace(/,/g,",</br>"));

  var my_center = {lat:data.latitude,lng:data.longitude};

  var map = new google.maps.Map(document.getElementById('my_map'), {
                zoom: 4,
                center: my_center
            });

  var marker = new google.maps.Marker({
                position: my_center,
                map: map,
                title: data.city
            });
});

}

</script>

reference:
https://www.maxmind.com/en/home
https://stackoverflow.com/questions/391979/how-to-get-clients-ip-address-using-javascript-only
https://developers.google.com/maps/documentation/javascript/adding-a-google-map

Sunday 15 April 2018

Official W5



react

react



ReactJs.Net

Install react package manager npm


create new react project

npx create-react-app my-app


debugging

cd my-app
npm start

deploy react

cd my-app
npm run build

host react on  local server

npm install -g serve
serve -s build

babel

https://marketplace.visualstudio.com/items?itemName=joshpeng.sublime-babel-vscode

react developer tools for chrome

https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi/related


<style>
my_ol, my_ul {
    padding-left: 30px;
}

.my_board-row:after {
    clear: both;
    content: "";
    display: table;
}

.my_status {
    margin-bottom: 10px;
}

.my_square {
    background: #fff;
    border: 1px solid #999;
    float: left;
    font-size: 24px;
    font-weight: bold;
    line-height: 34px;
    height: 34px;
    margin-right: -1px;
    margin-top: -1px;
    padding: 0;
    text-align: center;
    width: 34px;
}

    .my_square:focus {
        outline: none;
    }

.kbd-navigation .my_square:focus {
    background: #ddd;
}

.my_game {
    display: flex;
    flex-direction: row;
}

.my_game-info {
    margin-left: 20px;
}
</style>

<head>
<title>react</title>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>
    <div id="root"></div>
    <script type="text/babel">

      function Square(props) {
    return (
        <button className="my_square" onClick={props.onClick}>
            {props.value}
        </button>
    );
}

class Board extends React.Component {
    renderSquare(i) {
        return (
            <Square
                value={this.props.squares[i]}
                onClick={() => this.props.onClick(i)}
            />
        );
    }

    render() {
        return (
            <div>
                <div className="my_board-row">
                    {this.renderSquare(0)}
                    {this.renderSquare(1)}
                    {this.renderSquare(2)}
                </div>
                <div className="my_board-row">
                    {this.renderSquare(3)}
                    {this.renderSquare(4)}
                    {this.renderSquare(5)}
                </div>
                <div className="my_board-row">
                    {this.renderSquare(6)}
                    {this.renderSquare(7)}
                    {this.renderSquare(8)}
                </div>
            </div>
        );
    }
}

class Game extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            history: [{
                squares: Array(9).fill(null)
            }],
            stepNumber: 0,
            xIsNext: true
        };
    }

    handleClick(i) {
        const history = this.state.history.slice(0, this.state.stepNumber + 1);
        const current = history[history.length - 1];
        const squares = current.squares.slice();
        if (calculateWinner(squares) || squares[i]) {
            return;
        }
        squares[i] = this.state.xIsNext ? 'X' : 'O';
        this.setState({
            history: history.concat([{
                squares: squares
            }]),
            stepNumber: history.length,
            xIsNext: !this.state.xIsNext,
        });
    }

    jumpTo(step) {
        this.setState({
            stepNumber: step,
            xIsNext: (step % 2) === 0,
        });
    }

    render() {
        const history = this.state.history;
        const current = history[this.state.stepNumber];
        const winner = calculateWinner(current.squares);

        const moves = history.map((step, move) => {
            const desc = move ?
                'Go to move #' + move :
                'Go to game start';
            return (
                <li key={move}>
                    <button onClick={() => this.jumpTo(move)}>{desc}</button>
                </li>
            );
        });

        let status;
        if (winner) {
            status = 'Winner: ' + winner;
        } else {
            status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
        }

        return (
            <div className="my_game">
                <div className="my_game-board">
                    <Board
                        squares={current.squares}
                        onClick={(i) => this.handleClick(i)}
                    />
                </div>
                <div className="my_game-info">
                    <div>{status}</div>
                    <ol>{moves}</ol>
                </div>
            </div>
        );
    }
}

// ========================================

ReactDOM.render(
    <Game />,
    document.getElementById('root')
);

function calculateWinner(squares) {
    const lines = [
        [0, 1, 2],
        [3, 4, 5],
        [6, 7, 8],
        [0, 3, 6],
        [1, 4, 7],
        [2, 5, 8],
        [0, 4, 8],
        [2, 4, 6],
    ];
    for (let i = 0; i < lines.length; i++) {
        const [a, b, c] = lines[i];
        if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
            return squares[a];
        }
    }
    return null;
}


    </script>
</body>

reference:
https://react-cn.github.io/react/downloads.html
https://html5hive.org/react-tutorial/
https://reactjs.org/docs/react-api.html
https://reactjs.org/docs/add-react-to-a-new-app.html
https://www.npmjs.com/get-npm

javascript consume web api


user ID:
id user id title body




reference:
https://jsonplaceholder.typicode.com/posts/
https://www.c-sharpcorner.com/article/call-web-api-using-jquery-ajax-in-asp-net-core/

<style>
#my_table thead{
    background-color:cadetblue;
    text-align:center;
}

#my_table tbody>tr:nth-child(2n+1){
    background-color:grey;
}

#my_table tbody > tr:nth-child(2n) {
    background-color: darksalmon;
}

#my_combobox{
    width:100px;
}
</style>

<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>

<br />
user ID:
        <select id="my_combobox" onchange="my_combobox_onchange()"></select>
    <br />
<table id="my_table">
        <thead>
<tr>
                <td>id</td>
                <td>user id</td>
                <td>title</td>
                <td>body</td>
            </tr>
</thead>
        <tbody></tbody>
    </table>
<script type="text/javascript">
        $(document).ready(load_api());


var item_list = [];
var loading_finish = false;

function load_api() {
    $.ajax({
        type: "GET",
        url: "https://jsonplaceholder.typicode.com/posts",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (data) {
            //alert(JSON.stringify(data));

            $.each(data, function (i, item) {

                item_list.push(new my_class(item.userId, item.id, item.title, item.body));
             
            }); //End of foreach Loop 
            //console.log(data);

            populate_combobox();

        }, //End of AJAX Success function

        failure: function (data) {
            alert(data.responseText);
        }, //End of AJAX failure function
        error: function (data) {
            alert(data.responseText);
        } //End of AJAX error function

    });

}

class my_class {
    constructor(userId, id, title, body) {
        this.userId = userId;
        this.id = id;
        this.title = title;
        this.body = body;
    }
}

function populate_combobox() {
    var unique_userId = [];
    $("#my_combobox").append(new Option("all", 0));

    $.each(item_list, function (i, item) {
        if (unique_userId.indexOf(item.userId) < 0) {
            unique_userId.push(item.userId);
        }
    });

    $.each(unique_userId, function (i, item) {
        $("#my_combobox").append(new Option(item, i+1));
    });
}

function my_combobox_onchange() {

    $("#my_table tbody > tr").remove();

    var my_selected = $("#my_combobox option:selected").text();
    //alert($("#my_combobox option:selected").text());
    $.each(item_list, function (i, item) {
        if (item.userId == my_selected || my_selected=="all") {

            var rows = "<tr>" +
                    "<td id='id'>" + item.id + "</td>" +
                    "<td id='userId'>" + item.userId + "</td>" +
                    "<td id='title'>" + item.title + "</td>" +
                    "<td id='body'>" + item.body + "</td>" +
                //"<td id='AdmissionDate'>" + Date(item.admissionDate,
                //    "dd-MM-yyyy") + "</td>" +
                    "</tr>";
                $('#my_table').append(rows);
        }
    });
}

    </script>

Thursday 12 April 2018

css horizontal scroll


item 1
item 2
item 3
item 4
item 5
item 6
item 7
item 8


<style>
.horizontal-scroll-wrapper {
    width: 200px;
    height: 600px;
    overflow-y: auto;
    overflow-x: hidden;
    transform: rotate(-90deg) translateY(-200px);
    transform-origin: right top;
}

    .horizontal-scroll-wrapper > div {
        width: 200px;
        height: 200px;
        background-color: gold;
        margin: 10px 0;
        transform: rotate(90deg) translateX(200px);
        transform-origin: right top;
        text-align:center;
        padding-top:30px;
        color: red;
        font-size: 30px;
    }
</style>

 <div class="horizontal-scroll-wrapper">
        <div>item 1</div>
        <div>item 2</div>
        <div>item 3</div>
        <div>item 4</div>
        <div>item 5</div>
        <div>item 6</div>
        <div>item 7</div>
        <div>item 8</div>
    </div>

reference:
https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-snap-type
https://css-tricks.com/pure-css-horizontal-scrolling/

Monday 9 April 2018

javascript drag & drop


  to-do-1
  to-do-2
  to-do-3
  to-do-4
  to-do-5
  to-do-6



<style>
.to-do-item{
    height:100%;
    width:100%;
    display:block;
    cursor:grabbing;
    text-align:center;
    font-size:40px;
    color: red;
}

.to-do-tab {
    height: 50px;
    width: 80%;
    display: block;
    position: relative;
    margin: 10px 0;
}

#to-dos{
    display:block;
    height:100%;
    width:100%;
    position:relative;
}

#to-dos>div:nth-child(2n+1){
    background-color:yellow;
}

#to-dos>div:nth-child(2n) {
    background-color: cyan;
}

</style>
<head>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"></link>

<script type="text/javascript">
var drag_id, drag_parent_id, enter_id, enter_parent_id;

function allowDrop(ev) {
    ev.preventDefault();
}

function drag(ev) {
    ev.dataTransfer.setData("text", ev.target.id);

    drag_id = ev.target.id;
    drag_parent_id = ev.target.parentNode.id;

    document.getElementById("status").innerHTML = "drag event -- dragged item: "+drag_id + " || drag container: " + drag_parent_id;
}

function drop(ev) {
    ev.preventDefault();
    var data = ev.dataTransfer.getData("text");
    ev.target.parentNode.appendChild(document.getElementById(data));

    //if not droping on original container && itself
    if (ev.target.id != drag_parent_id && ev.target.id != drag_id) {

        document.getElementById("status3").innerHTML = "drop event -- drop container: "+ev.target.parentNode.id + " || drop target: " + ev.target.id + " || dropped item: " + data;

        //drag container append orignal enter child
        document.getElementById(drag_parent_id).appendChild(document.getElementById(enter_id));

        //remove original child from enter container
        document.getElementById(enter_parent_id).removeChild(document.getElementById(enter_id));
     
    }

}

function dragEnter(ev) {
    //filter out drag enter on original container
    if (event.target.id != drag_parent_id && event.target.id != drag_id) {

        document.getElementById("status2").innerHTML = "drag enter event -- drop target: "+ event.target.id + " || drop target container: " + ev.target.parentNode.id;

        enter_id = event.target.id;

        enter_parent_id = ev.target.parentNode.id;
    }
}

    </script>
</head>

<br />
<div id="to-dos">
<div class="to-do-tab" id="div1" ondragenter="dragEnter(event)" ondragover="allowDrop(event)" ondrop="drop(event)">
<div class="to-do-item" draggable="true" id="drag1" ondragstart="drag(event)">
<i class="fa fa-hand-peace-o" style="font-size: 24px;"></i>&nbsp;&nbsp;to-do-1</div>
</div>
<div class="to-do-tab" id="div2" ondragenter="dragEnter(event)" ondragover="allowDrop(event)" ondrop="drop(event)">
<div class="to-do-item" draggable="true" id="drag2" ondragstart="drag(event)">
<i class="fa fa-cny" style="font-size: 24px;"></i>&nbsp;&nbsp;to-do-2</div>
</div>
<div class="to-do-tab" id="div3" ondragenter="dragEnter(event)" ondragover="allowDrop(event)" ondrop="drop(event)">
<div class="to-do-item" draggable="true" id="drag3" ondragstart="drag(event)">
<i class="fa fa-transgender-alt" style="font-size: 24px;"></i>&nbsp;&nbsp;to-do-3</div>
</div>
<div class="to-do-tab" id="div4" ondragenter="dragEnter(event)" ondragover="allowDrop(event)" ondrop="drop(event)">
<div class="to-do-item" draggable="true" id="drag4" ondragstart="drag(event)">
<i class="fa fa-superscript" style="font-size: 24px;"></i>&nbsp;&nbsp;to-do-4</div>
</div>
<div class="to-do-tab" id="div5" ondragenter="dragEnter(event)" ondragover="allowDrop(event)" ondrop="drop(event)">
<div class="to-do-item" draggable="true" id="drag5" ondragstart="drag(event)">
<i class="fa fa-refresh fa-spin" style="font-size: 24px;"></i>&nbsp;&nbsp;to-do-5</div>
</div>
<div class="to-do-tab" id="div6" ondragenter="dragEnter(event)" ondragover="allowDrop(event)" ondrop="drop(event)">
<div class="to-do-item" draggable="true" id="drag6" ondragstart="drag(event)">
<i class="fa fa-space-shuttle" style="font-size: 24px;"></i>&nbsp;&nbsp;to-do-6</div>
</div>
</div>
<div id="status">
</div>
<div id="status2">
</div>
<div id="status3">
</div>

reference:
https://shopify.github.io/draggable/
https://www.w3schools.com/html/html5_draganddrop.asp
https://www.w3schools.com/howto/howto_js_todolist.asp
https://jsfiddle.net/phusick/Rceua/
https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_ondragenter

Friday 6 April 2018

贸易战爆发 中国楼市将面临三种选择

中美贸易战的扩大化,似乎已很难避免!

  美国方面公布了针对中国1300多种商品、超过500亿美元货值的“惩罚清单”(加征25%的关税)。4月4日,中国也公布了针对美国的,同样规模的“惩罚清单”。

  中国开列的“惩罚清单”是:对原产于美国的大豆、汽车、飞机等进口商品加征25%的关税,涉及金额也是大约500亿美元。

  毫无疑问,如果两国的“惩罚清单”都落实的话,将诱发一轮通胀。

  其中对中国影响最大的进口产品,是大豆。

  很多中国人可能不知道,中国基本上放弃了大豆的生产。以刚刚过去的2017年为例,中国进口大豆9554万吨,相当于给每个中国人进口了136斤大豆。而中国自己生产的大豆,2017年不足1500万吨。


  也就是说,在大豆这种农作物上,中国的“进口依存度”达到了87%左右,远远超过石油、天然气。
  为什么中国基本上放弃了大豆的生产?因为中国的产量低,而需求量又非常大。如果中国不进口大豆,完全自己生产,则需要拿出大约三分之一的耕地来种大豆,这样中国人需要的小麦、大米就要大量进口。

  也就是说,中国目前的耕地,要维持14亿人较高质量的生活,是明显不够的。所以中国基本放弃了产量低的大豆,而依赖进口。大豆主要用作饲料(也可以榨油),养活了中国4.3亿头猪,以及其他家禽家畜,最终转换为中国人需要的肉类。

  目前全球可以在国际间交易的大豆,70%都被中国买走了。其中巴西为中国生产了将近一半的“进口大豆”,其次是美国。2017年中国从美国进口大豆3285万吨,占中国进口量的三分之一,金额大约120亿美元,超过了中国从美国进口汽车和飞机的金额。

  全球主要大豆出口国就是巴西和美国,此外还有阿根廷等一些国家。如果中国被迫对美国大豆加收25%的特别关税,则巴西等国的大豆肯定也会借机涨价,最终将引发中国肉价的上涨。而肉价,特别是猪肉价格,对中国的CPI影响很大。

  也就是说,如果中美之间爆发中等以上规模的贸易战,中国的CPI肯定会跳升。如果逼近3%,央行加息就成为必然。

  而美国方面,由于居民日常生活高度依赖中国产品,对中国商品普遍加税后,通胀也会上升,最终逼迫美联储以更快节奏加息。

  从这个意义上说,中美贸易战对于两国楼市都构成利空,因为都会带来加息。

  但这仅仅是影响的第一波。随后,政策就会发生调整。原因很简单,因为就业开始出问题了。

  按照中国方面公布的数据,2017年中国对美国出口4298亿美元,从美国进口1539亿美元。可见,如果中美爆发全面贸易战,中国受的影响比美国大,损失的工作岗位可能数倍、甚至十倍于美国。

  而2017年又是中国提高经济质量一年,政府在“大基建+PPP”上开始收紧,一些没有效益的项目、超过地方财政承受能力的项目开始下马;2017年还是环境攻坚战的关键年份,很多落后产能被迫停产、转产。在这种情况下,如果对美贸易出现大幅下滑,失业率大增,还要被迫加息。这时候,楼市上浮的利率可能会下降。

  换句话说:中国目前没有正式加息,没有提高银行存贷款基准利率;如果为了抑制CPI而被迫正式加息,为了降低对楼市的负面影响,此前在基准利率基础上的利率上浮,会有所下降。

  对于一二线城市楼市,政府尽量会做到:让成交量放大,但价格基本不涨,或者上涨轻微。至于三四线城市,很多房价仍然在飞涨之中。

  目前中国经济的三大部门:政府、企业和家庭,只有政府和家庭两大部门尚有一些“加杠杆”的空间,企业基本上没有了。所以,如果面对突如其来的大规模贸易战,只能在地方债和楼市上想办法。

  下面,我给出中美冲突三种情况下,对于中国楼市的影响:

  1、中等或中等规模以下的贸易战,对于楼市影响偏利空,因为中国会稳定人民币汇率(并略有升值)。同时,中国会小心维持中美利差,美国加息的时候中国会引导利率上行。

  2、大规模贸易战,中国失业率上升、出现输入型通胀、被迫加息,则针对楼市的利率上浮开始下降或取消,楼市调控会适度放松,对楼市构成偏好的影响,但房价不会允许大涨。

  3、中美彻底翻脸。这时候中国失业率飙升、出现输入型通胀、被迫加息,楼市调控就可能逆转,人民币或将大幅贬值,房价出现新一波上涨。当然,人民币计价下,大家的工资收入也大幅增加。2017年之前的买房家庭,按揭压力突然大幅减少。整体而言,发生前两种情况的可能性偏大,第三种情况可能性极小。

  反正不管怎样,2018年楼市调控都不能让市场真正入冬。未来,各地政府会通过降低落户门槛、增加户籍人口来发放房票,对冲限购限贷带来的负面影响;还会提高公积金贷款上限,以保护刚需、改善型需求的名义,增加楼市的需求量,让成交量获得维持。

Tuesday 3 April 2018

entity framework code first




----------------------------------------------------------

program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var db = new my_context())
            {
             

                var students = db.students.ToList();
                var courses = db.coruses.ToList();
                var teachers = db.teachers.ToList();

                foreach(var s in students)
                {
                    Console.WriteLine("student: " + s.name);
                    Console.Write("courses: ");

                    var courses_taken_by_student = courses.Where(x => x.student_id == s.id);

                    foreach(var c in courses_taken_by_student)
                    {
                        Console.Write(c.name + " ");
                    }

                    Console.WriteLine("");
                    Console.WriteLine("");
                }

                foreach(var t in teachers)
                {
                    Console.WriteLine("teacher: " + t.name);

                    var courses_taught_by_teacher = courses.Where(x => x.teacher_id == t.id);

                    foreach(var c in courses_taught_by_teacher)
                    {
                        Console.WriteLine("courses: "+ c.name);

                        var student_taking_course = students.Where(x => x.id == c.student_id);
                        Console.Write("student: ");

                        foreach(var s in student_taking_course)
                        {
                            Console.Write(s.name + " ");
                        }

                        Console.WriteLine("");
                        Console.WriteLine("");
                    }
                }
            }

            Console.Read();
        }
    }

    public class student
    {
        [Key]
        public int id { get; set; }
        public string name { get; set; }

        public virtual ICollection<course> courses { get; set; }
    }

    public class course
    {
        [Key]
        public int id { get; set; }
        public string name { get; set; }
        public int student_id { get; set; }
        public int teacher_id { get; set; }

        [ForeignKey("student_id")]
        public virtual student Student { get; set; }

        [ForeignKey("teacher_id")]
        public virtual teacher Teacher { get; set; }
    }

    public class teacher
    {
        [Key]
        public int id { get; set; }
        public string name { get; set; }
     
        public virtual ICollection<course> courses { get; set; }
    }

    public class my_context : DbContext
    {
        public my_context() : base("name = mystring") { }

        public virtual DbSet<student> students { get; set; }
        public virtual DbSet<course> coruses { get; set; }
        public virtual DbSet<teacher> teachers { get; set; }
    }
}

------------------------------------------------------------------
//configuration.cs in migration

namespace ConsoleApp2.Migrations
{
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Migrations;
    using System.Linq;

    internal sealed class Configuration : DbMigrationsConfiguration<ConsoleApp2.my_context>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
            ContextKey = "ConsoleApp2.my_context";
        }

        protected override void Seed(ConsoleApp2.my_context context)
        {
            //  This method will be called after migrating to the latest version.

            //  You can use the DbSet<T>.AddOrUpdate() helper extension method 
            //  to avoid creating duplicate seed data.

            context.students.AddOrUpdate(new student { name = "wang",id=3 });
            context.students.AddOrUpdate(new student { name = "li",id=5 });
            context.students.AddOrUpdate(new student { name = "zhang",id=10 });
            context.students.AddOrUpdate(new student { name = "zhao", id=15 });

            context.teachers.AddOrUpdate(new teacher { name = "T1",id=3 });
            context.teachers.AddOrUpdate(new teacher { name = "T2",id=8 });

            context.SaveChanges();

            var teacher_1 = context.teachers.SingleOrDefault(x => x.name == "T1").id;
            var teacher_2 = context.teachers.SingleOrDefault(x => x.name == "T2").id;

            var student_1 = context.students.SingleOrDefault(x => x.name == "wang").id;
            var student_2 = context.students.SingleOrDefault(x => x.name == "li").id;
            var student_3 = context.students.SingleOrDefault(x => x.name == "zhang").id;
            var student_4 = context.students.SingleOrDefault(x => x.name == "zhao").id;

            context.coruses.AddOrUpdate(new course { name = "physic", student_id = student_1,teacher_id=teacher_1,id=5 });
            context.coruses.AddOrUpdate(new course { name = "math", student_id = student_1,teacher_id=teacher_1,id=10 });
            context.coruses.AddOrUpdate(new course { name = "math", student_id = student_2,teacher_id=teacher_2,id=13 });
            context.coruses.AddOrUpdate(new course { name = "art", student_id = student_2,teacher_id=teacher_1,id=17 });
            context.coruses.AddOrUpdate(new course { name = "art", student_id = student_3,teacher_id=teacher_2,id=22 });
            context.coruses.AddOrUpdate(new course { name = "art", student_id = student_4,teacher_id=teacher_2,id=26 });
            context.coruses.AddOrUpdate(new course { name = "math", student_id = student_3,teacher_id=teacher_2,id=36 });       

            context.SaveChanges();
        }
    }
}

------------------------------------------------------------------
//first migration.cs
namespace ConsoleApp2.Migrations
{
    using System;
    using System.Data.Entity.Migrations;
    
    public partial class first_migration : DbMigration
    {
        public override void Up()
        {
            CreateTable(
                "dbo.teachers",
                c => new
                    {
                        id = c.Int(nullable: false, identity: true),
                        name = c.String(),
                    })
                .PrimaryKey(t => t.id);
            
            AddColumn("dbo.courses", "teacher_id", c => c.Int(nullable: false));
            CreateIndex("dbo.courses", "teacher_id");
            AddForeignKey("dbo.courses", "teacher_id", "dbo.teachers", "id", cascadeDelete: true);
        }
        
        public override void Down()
        {
            DropForeignKey("dbo.courses", "teacher_id", "dbo.teachers");
            DropIndex("dbo.courses", new[] { "teacher_id" });
            DropColumn("dbo.courses", "teacher_id");
            DropTable("dbo.teachers");
        }
    }
}
-----------------------------------------------
//app.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
  </startup>
  <connectionStrings>
    <add name="mystring"
         connectionString= "Server=DESKTOP-2286VQK\SQLEXPRESS;Database=test;Trusted_Connection=True;" providerName = "System.Data.SqlClient"/>
  </connectionStrings>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
</configuration>

------------------------------------------------------------
//console

  student: wang
courses: physic math

student: li
courses: math art

student: zhang
courses: art math

student: zhao
courses: art

teacher: T1
courses: physic
student: wang

courses: math
student: wang

courses: art
student: li

teacher: T2
courses: math
student: li

courses: art
student: zhang

courses: art
student: zhao

courses: math
student: zhang

reference:
https://www.tutorialspoint.com/entity_framework/entity_framework_first_example.htm
https://stackoverflow.com/questions/4867602/entity-framework-there-is-already-an-open-datareader-associated-with-this-comma
https://msdn.microsoft.com/en-us/data/jj591621