Advertiser と呼ばれる EF のエンティティと、Client と呼ばれる別のエンティティがあります。広告主には、ドロップダウンリストから選択されるクライアントと呼ばれる関連付けフィールドがあります。この関連付けをデータベースに保存する方法を知りたいです。私が使用したアプローチは、(Id を使用して) Client オブジェクトを検索し、この Client オブジェクトを Advertiser.Client ナビゲーション プロパティに割り当てることです。この Advertiser プロパティを追加するまでに、既存のエンティティに関連付けられた Advertiser を追加していることを願っていました。しかし、これは結果ではありませんでした。代わりに、新しいクライアント レコードもテーブルに追加されました。これを修正するにはどうすればよいですか?
完全な説明とコードビットは以下のとおりです...
public class Advertiser
{
public int Id { get; set; }
public string Name { get; set; }
//Navigation Properties
public virtual Client Client { get; set; }
}
そして別のクライアントと呼ばれる
public class Client
{
public Client()
{
Advertisers = new List<Advertiser>();
}
public int Id { get; set; }
public string Name { get; set; }
// Navigation Properties
public virtual ICollection<Advertiser> Advertisers { get; set; }
}
一連のクライアントが別のビューでデータベースに追加されます。ユーザーが広告主ビューに到達すると、作成オプションが表示されます。私が作成したいのは、ユーザーがすべてのクライアントを含むドロップダウン リストからクライアントを選択できるようにすることです。この広告主をそのクライアントに関連付けたいと考えています。
これはコントローラーのコードです。
//
// POST: /Advertiser/Create
[HttpPost]
public ActionResult Create(Advertiser advertiser,int Id)
{
if (ModelState.IsValid)
{
advertiser.Client = clientRepo.Retrieve(Id); // Finds and returns a Client object
System.Diagnostics.Debug.WriteLine("Saving Advertiser, with int Id = {0} and Client.Id = {1}", Id, advertiser.Client.Id);
repo.Create(advertiser);
repo.SaveChanges();
return RedirectToAction("Index");
}
return View(advertiser);
}
広告主ビューは、ドロップダウン リストにすべてのクライアントを入力し、現在選択されているクライアントの ID を返します。
<div class="editor-field">
@{
var clients = new Repository<Client>().FetchAll();
var clientLists = new SelectList(clients, "Id", "Name");
}
@Html.DropDownList("Id", clientLists)
</div>
現在、このビューは正しい Id を正しく返します。Debug.Writeline は、正しい Id が返されていることも確認します。問題はその後の展開…
既存の Client エンティティに関連付けられた新しい Advertiser を挿入する代わりに、最初に Advertiser を挿入し、次に Client エンティティのコピーをデータベースに挿入します。これにより、主キー (Id) のみが異なる重複したクライアントが発生します。
これは、Advertiser.Client プロパティに対して適切なクライアントを見つけて参照する代わりに、外部キーを公開して外部キーを渡すことで解決できることを知っています。しかし、可能であれば、外部キーを公開せずにこれを行うことをお勧めします。これを行う方法はありますか?...つまり、私は何を間違っていますか?
この質問に答えるのに Repository クラスで何が起こっているかが役立つ場合は、以下に追加しました。
public OperationStatus Create(TEntity item)
{
OperationStatus status = new OperationStatus {Status = true};
var value = DataContext.Set<TEntity>().Add(item);
if(value == null)
{
status = null;
}
return status;
}
public TEntity Retrieve(int id)
{
return DataContext.Set<TEntity>().Find(id);
}