实体框架多对多关闭模式更新 - 如何 [英] Entity Framework Many to Many Disconnected Mode Update - HowTo

查看:67
本文介绍了实体框架多对多关闭模式更新 - 如何的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用EF 6 Code First,我有以下数据库表:

I am using EF 6 Code First, and I have the following database tables:

帐户

合同

AccountContract

AccountContract

AccountContract是一个联结表,它有两个指向Account对象ID的主外键和一个合同对象ID。没有什么太花哨的了。然后我读取一些数据并尝试更新Account对象的ICollection of Contracts。
这是我不清楚的地方,以下是失败的代码和我发现的代码,我想知道这是否是正确的做事方式,还是有更好的方法。提前感谢您的想法/意见。

AccountContract is a junction table that has two primary foreign keys that point to an Account object ID and a Contract object ID. Nothing too fancy there. I am then reading in some data and attempting to update the Account object's ICollection of Contracts. This is where things become unclear for me, following is the code that fails and the code I've found to work, and I wish to know if this is the correct way of doing things, or is there a better way. Thanks in advance for your thoughts/comments.

// Example #1 in Connected State: Successfully updates the junction table, but I get a duplicate contract created.
using (var db = new ClientDbContext())
{
	var account = db.accounts
		.Where(w => w.account_id == 41) // Test Account
		.FirstOrDefault();

	if (account != null && !account.contracts.Any(a => a.contract_id == 5)) // Test Contract.
	{
		contracts newContract = new contracts();

		newContract.contract_id = 5;
		newContract.contract_name = "Name";
		newContract.contract_description = "Some Text";
		
		account.contracts.Add(newContract);

		db.Entry(account).State = System.Data.Entity.EntityState.Modified;
		db.SaveChanges();
	}
}

// AccountController Update Function.
public void Update(account item)
{
	using (var db = new ClientDbContext())
	{
		try
		{
			db.accounts.Create(item); // Probably duplicate is created as we are creating a new Account item. All makes sense.
			db.SaveChanges();
		}
		catch (Exception e)
		{
			throw e;
		}
	}
}

// Example #2 in Disconnected State: Doesn't work, no changes in the database.
int accountID = 41;
int contractID = 5;
var controller = new AccountController();

var account = controller.GetByID(accountID); // Get the test Account.

if (account != null && !account.contracts.Any(a => a.contract_id == contractID))
{
	contracts newContract = new contracts();

	newContract.contract_id = 5;
	newContract.contract_name = "Name";
	newContract.contract_description = "Some Text";
	
	account.contracts.Add(newContract);

	controller.Update(account);
}

// AccountController Update Function.
public void Update(account item)
{
	using (var db = new ClientDbContext())
	{
		try
		{
			db.accounts.Attach(item); // From reading MSDN it looks like this is the way to do it, but it doesn't create any database objects.
			db.Entry(item).State = System.Data.Entity.EntityState.Modified;
			db.SaveChanges();
		}
		catch (Exception e)
		{
			throw e;
		}
	}
}

// Example #3 in Disconnected State: Works but I don't know if it is the right way, it seems a bit hacky. Only code that changes is the Update function in my controller.

// AccountController Update Function.
public void UpdatePricingContracts(account item)
{
	using (var db = new ClientDbContext())
	{
		try
		{
			// I don't understand why this is needed.
			// To me it feels like this would create a new account object, but it doesn't.
			// It actually STOPS the creation of a duplicate account object.
			db.accounts.Add(item);

			// I guess because even thought we Add the item, we tell the DbContext it is Unchanged. I thought that was what Attach is for.
			db.Entry(item).State = System.Data.Entity.EntityState.Unchanged;

			// Marking that the Contracts have changed.
			foreach (var contract in item.contracts)
			{
				db.Entry(contract).State = System.Data.Entity.EntityState.Modified;
			}

			db.SaveChanges();
		}
		catch (Exception e)
		{
			throw e;
		}
	}
}

推荐答案

Hi ismithers,

Hi ismithers,

如果名为contracts的对象已经在您的数据库中,并且您希望在联结表中添加记录并修改合约的价值,你可以参考下面的代码。

If the object named contracts have been in your database, and you want add the record in your junction table and modify the value of contracts, you could refer to the following code.

using (var db = new Model1()) { var account = db.Accounts .Where(w => w.account_id == 1) // Test Account .FirstOrDefault(); var contract = db.Contracts.Find(5); if (account != null && !account.Contracts.Any(a => a.contract_id == 5)) // Test Contract. { contract.contract_name = "Name";

合约。 contract_description =" Some Text" ;;
account.Contracts.Add(contract);
db.SaveChanges();
}
}

contract.contract_description = "Some Text"; account.Contracts.Add(contract); db.SaveChanges(); } }

祝你好运,

Cole Wu


这篇关于实体框架多对多关闭模式更新 - 如何的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆