代码优先迁移创建添加属性

时间:2016-04-29 16:33:44

标签: asp.net-mvc entity-framework asp.net-mvc-4 ef-migrations

我正在尝试使用具有以下属性的代码首先创建一个表:

import sys, os, base64, datetime, hashlib, hmac
import requests
method = 'GET'
service = 's3'
host = 's3-us-west-2.amazonaws.com'
region = 'us-west-2'
endpoint = 'http://s3-us-west-2.amazonaws.com'
request_parameters = ''

def sign(key, msg):
    return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest()

def getSignatureKey(key, dateStamp, regionName, serviceName):
    kDate = sign(('AWS4' + key).encode('utf-8'), dateStamp)
    kRegion = sign(kDate, regionName)
    kService = sign(kRegion, serviceName)
    kSigning = sign(kService, 'aws4_request')
    return kSigning

access_key = os.environ.get('AWS_ACCESS_KEY_ID')
secret_key = os.environ.get('AWS_SECRET_ACCESS_KEY')
if access_key is None or secret_key is None:
    print 'No access key is available.'
    sys.exit()

t = datetime.datetime.utcnow()
amzdate = t.strftime('%Y%m%dT%H%M%SZ')
datestamp = t.strftime('%Y%m%d') # Date w/o time, used in credential scope

canonical_uri = '/bucket/key'
canonical_querystring = request_parameters
canonical_headers = 'host:' + host + '\n' + 'x-amz-content-sha256:UNSIGNED-PAYLOAD' + '\n' + 'x-amz-date:' + amzdate + '\n'
signed_headers = 'host;x-amz-content-sha256;x-amz-date'
payload_hash = 'UNSIGNED-PAYLOAD'
canonical_request = method + '\n' + canonical_uri + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + signed_headers + '\n' + payload_hash
algorithm = 'AWS4-HMAC-SHA256'
credential_scope = datestamp + '/' + region + '/' + service + '/' + 'aws4_request'
string_to_sign = algorithm + '\n' +  amzdate + '\n' +  credential_scope + '\n' +  hashlib.sha256(canonical_request).hexdigest()
signing_key = getSignatureKey(secret_key, datestamp, region, service)
signature = hmac.new(signing_key, (string_to_sign).encode('utf-8'), hashlib.sha256).hexdigest()
authorization_header = algorithm + ' ' + 'Credential=' + access_key + '/' + credential_scope + ', ' +  'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + signature
headers = {'x-amz-date':amzdate, 'x-amz-content-sha256': 'UNSIGNED-PAYLOAD', 'Authorization':authorization_header}
request_url = endpoint + canonical_uri

print '\nBEGIN REQUEST++++++++++++++++++++++++++++++++++++'
print 'Request URL = ' + request_url
r = requests.get(request_url, headers=headers)

print '\nRESPONSE++++++++++++++++++++++++++++++++++++'
print 'Response code: %d\n' % r.status_code
print r.text

我向两个表添加了所需的关系:

public class HistoryRead
{
    [Key]
    public int Id { get; set; }

    [Required]
    public int Book_Id { get; set; }

    [Required]
    [StringLength(128)]
    public string User_Id { get; set; }

    public virtual AspNetUser AspNetUser { get; set; }

    public virtual Book Book { get; set; }
}

和:

public partial class AspNetUser
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public AspNetUser()
    {

        HistoryReads = new HashSet<HistoryRead>();

    }

    public string Id { get; set; }

    [Display(Name = "Email")]
    [DataType(DataType.EmailAddress)]
    [StringLength(256)]
    public string Email { get; set; }

    public virtual ICollection<HistoryRead> HistoryReads { get; set; }

}

然后我运行迁移并得到了这个结果!

 public partial class Book
{
    public Book()
    {

        HistoryReads = new HashSet<HistoryRead>();
    }
    [Key]
    public int Book_id { get; set; }

    [Required]
    [Display(Name ="User Name")]
    [StringLength(128)]
    public string User_ID { get; set; }



    public string UrlSlug { get; set; }



    [Required]
    [Display(Name = "Title Name")]
    [StringLength(70,MinimumLength =3)]
    public string Book_name { get; set; }


    public virtual ICollection<HistoryRead> HistoryReads { get; set; }

}
正如你在迁移生成的代码中看到的那样,我得到了一个名为“AspNetUser_Id”的额外属性,我不需要它,即使我试图删除它并继续我的工作我从db方面得到一个例外..所以如何解决这个问题,谢谢...

1 个答案:

答案 0 :(得分:0)

这正是我在迁移中应该期待的。您在HistoryRead中有一个虚拟的AspNetUser,而EF会创建一个AspNetUser_Id以将其与您的用户匹配。它不知道你想使用User_Id作为密钥。这就是抛出异常的原因。

它在书上工作的原因是因为它使用了_Id的约定,并且它知道它是书虚拟的外键。

我建议您从模型中删除User_Id和Book_Id。 EF将负责处理它所需要的关系和外键。这样,模型将更清晰,您可以通过虚拟访问它。

正如所提出的,如何向对象添加新关系的示例。

var historyObject = dbContext.Set<HistoryRead>().GetById(1);
var bookObject = dbContext.Set<Book>().GetByTitle("Example");
historyObject.Book = bookObject;
dbContext.Set<HistoryRead>().Update(historyObject);
await dbContext.SaveChangesAsync();