1

私はEntityFrameworkを使用して、2つのテーブルを更新しています。データベーススキーマは、自動インクリメントIDを持つCustomerテーブルと、外部キー関係を持つ子テーブルで構成されています。子テーブルには、顧客IDの複合キーとvarcharの2番目の列としての情報の2つの列しかありません。

ビューオブジェクトがあります:

public class CustomerView
{
    public long id { get; set; }
    public String firstName { get; set; }
    public String lastName { get; set; }
    public String streetAddress { get; set; }
    public String city { get; set; }
    public String state { get; set; }
    public String zip { get; set; }
    public String profession { get; set; }
    public String[] linesOfBusiness { get; set; }
}

これは、ビューオブジェクトとエンティティ間のマッピングクラスです。

internal static Customer getCustomerFromView(CustomerView customer)
{
    Customer newCustomer = new Customer
    {
        Customer_ID = customer.id,
        FirstName = customer.firstName,
        LastName = customer.lastName,
        Street = customer.streetAddress,
        City = customer.city,
        State = customer.state,
        Zip = customer.zip,
        Profession = customer.profession
    };
    foreach (String line in customer.linesOfBusiness)
    {
        newCustomer.LinesOfBusinesses.Add(new LinesOfBusiness { Customer_ID = customer.id, LineOfBusiness = line });
    }
    return newCustomer;
}

エンティティは問題なく作成できますが、エンティティを更新しようとすると、エンティティコレクションが既に初期化されているというエラーが発生します。更新方法は次のとおりです。

private void updateCustomer(CustomerView customer)
{
    using (LocalCustomerDB data = new LocalCustomerDB())
    {
        Customer dbCustomer = (from c in data.Customers where c.Customer_ID == customer.id select c).Single();
        Customer tempCustomer = CustomerMapper.getCustomerFromView(customer);
        dbCustomer.FirstName = tempCustomer.FirstName;
        dbCustomer.LastName = tempCustomer.LastName;
        dbCustomer.LinesOfBusinesses = tempCustomer.LinesOfBusinesses;
        dbCustomer.Profession = tempCustomer.Profession;
        dbCustomer.State = tempCustomer.State;
        dbCustomer.Street = tempCustomer.Street;
        dbCustomer.Zip = tempCustomer.Zip;
        dbCustomer.City = tempCustomer.City;
        data.SaveChanges();
    }
}

私はEntityFrameworkを初めて使用します。どこが間違っているのでしょうか?

ありがとう!

編集


コメントのリクエストに応じて、update()を呼び出しているコードがここにあります。

    public long saveCustomer(CustomerView customer)
        {
            long returnValue = 0;
            using (LocalCustomerDB data = new LocalCustomerDB())
            {
                if (customer.id > 0)
                {
                    updateCustomer(customer);
                    returnValue = customer.id;
                }
                else
                {
                    Customer newCustomer =
                    CustomerMapper.getCustomerFromView(customer);
                    data.Customers.AddObject(newCustomer);
                    data.SaveChanges();
                    returnValue = newCustomer.Customer_ID;
                }
            }
            return returnValue;
        }

スタックトレースは次のとおりです。

 at System.Data.Objects.DataClasses.RelationshipManager.InitializeRelatedCollection[TTargetEntity](String relationshipName, String targetRoleName, EntityCollection1 entityCollection)
    at CustomerRegistry.Customer.set_LinesOfBusinesses(EntityCollection`1
value) in C:\Users\Michael\Documents\Personal
Projects\CustomerRegistry\CustomerRegistry\CustomerRegistry\CustomerModel.Designer.cs:line
386
    at CustomerRegistry.Project_Code.DataAccess.CustomerRepository.updateCustomer(CustomerView
customer) in C:\Users\Michael\Documents\Personal
Projects\CustomerRegistry\CustomerRegistry\CustomerRegistry\Project
Code\DataAccess\CustomerRepository.cs:line 41
    at CustomerRegistry.Project_Code.DataAccess.CustomerRepository.saveCustomer(CustomerView
customer) in C:\Users\Michael\Documents\Personal
Projects\CustomerRegistry\CustomerRegistry\CustomerRegistry\Project
Code\DataAccess\CustomerRepository.cs:line 19
    at CustomerRegistry.CustomerEntry.Submit_Click(Object sender,
EventArgs e) in C:\Users\Michael\Documents\Personal
Projects\CustomerRegistry\CustomerRegistry\CustomerRegistry\CustomerEntry.aspx.cs:line
40
    at System.Web.UI.WebControls.Button.OnClick(EventArgs e)
    at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)
    at System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String
eventArgument)
    at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler
sourceControl, String eventArgument)
    at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
    at System.Web.UI.Page.ProcessRequestMain(Boolean
includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
4

2 に答える 2

0

コードファーストを使用してエンティティを実行しただけなので、100%ポジティブではありませんが、CustomerViewの子オブジェクトのコレクションに仮想修飾子がないようです。CustomerViewを次のように変更してみてください。

public class CustomerView
{
    public long id { get; set; }
    public String firstName { get; set; }
    public String lastName { get; set; }
    public String streetAddress { get; set; }
    public String city { get; set; }
    public String state { get; set; }
    public String zip { get; set; }
    public String profession { get; set; }
    public virtual String[] linesOfBusiness { get; set; }
}

linesOfBusinessの仮想修飾子に注目してください。

于 2012-07-13T14:37:37.510 に答える
0

変更してみてください

dbCustomer.LinesOfBusinesses = tempCustomer.LinesOfBusinesses;

tempCustomer.LinesOfBusinesses.ForEach(z => dbCustomer.LinesOfBusinesses.Add(z));

例外がまだここにあることを知らせてください。ナビゲーションプロパティには何も影響を与えられないと思います(dbCustomer.LinesOfBusinesses)。オブジェクトを追加、削除、クエリできます。ただし、参照されるインスタンスを変更することはできません。

于 2012-07-13T15:07:26.250 に答える