在花了几天时间尝试使用 EF 和 DDD 设置一个简单的应用程序之后,我不得不说我感到非常沮丧,并认为我最好还是使用 Linq-to-SQL 并忘记所有关于 DDD 和 EF 的事情。
英孚
a) 你不能有正确的只读集合
b)当您从一组子项中删除某些内容时,您经常会收到无法更改关系,因为一个或多个外键属性是不可为空的消息
c) 没有简单的方法可以删除父项的所有子项并重新插入它们
鉴于我发现的变通方法看起来很讨厌,所有这些对我来说几乎都是阻碍。是否有人设法组建了一个简单的存储库来解决这些问题?
如果是的话,你会愿意分享一些代码吗?!?
另外,我知道这是一个大话题,是否有人亲身体验过大型 Web 应用程序中的任何 DDD 优势?我们都知道这个理论,但如果它真的值得麻烦,那么有一个想法会很好!
好的,到目前为止,我可以做的最好的事情是在查询某些内容时使用 AsNoTracking() ,而不必做各种疯狂的解决方法。这样我就可以得到我的信息,而 EF 就不用管它在我背后做的任何事情。我现在可以从集合中删除,并且我也可以删除(谁会认为 id 必须为此返回 sql!)有谁知道使用 AsNoTracking 的任何陷阱?至于我可以根据我的对象生成 SQL 并填充它们或更新/删除它们,我很好。整个跟踪的事情还是走得太远了?
namespace EShop.Models.Repositories
{
public class CustomerRepository : BaseRepository, IRepository<Customer, Int32>
{
public CustomerRepository() : base(new EShopData()) { }
#region CoreMethods
public void InsertOrUpdate(Customer customer)
{
if (customer.CustomerId > 0)
{
// you cannot use remove, if you do you ll attach and then you ll have issues with the address/cards below
// dbContext.Entry<CustomerAddress>(address).State = EntityState.Added; will fail
dbContext.Database.ExecuteSqlCommand("DELETE FROM CustomerAddress WHERE CustomerId = @CustomerId", new SqlParameter("CustomerId", customer.CustomerId));
dbContext.Database.ExecuteSqlCommand("DELETE FROM CreditCard WHERE CustomerId = @CustomerId", new SqlParameter("CustomerId", customer.CustomerId));
foreach (var address in customer.Addresses)
dbContext.Entry<CustomerAddress>(address).State = EntityState.Added;
foreach (var card in customer.CreditCards)
dbContext.Entry<CreditCard>(card).State = EntityState.Added;
dbContext.Entry<Customer>(customer).State = EntityState.Modified;
}
else
{
dbContext.Entry<Customer>(customer).State = EntityState.Added;
foreach (var card in customer.CreditCards)
dbContext.Entry<CreditCard>(card).State = EntityState.Added;
foreach (var address in customer.Addresses)
dbContext.Entry<CustomerAddress>(address).State = EntityState.Added;
}
}
public void Delete(int customerId)
{
var existingCustomer = dbContext.Customers.Find(customerId);
if (existingCustomer != null)
{
//delete cards
var creditCards = dbContext.CreditCards.Where(c => c.CustomerId == customerId);
foreach (var card in creditCards)
dbContext.Entry<CreditCard>(card).State = EntityState.Deleted;
//delete addresses
var addresses = dbContext.CustomerAddresses.Where(c => c.CustomerId == customerId);
foreach (var address in addresses)
dbContext.Entry<CustomerAddress>(address).State = EntityState.Deleted;
//delete basket
dbContext.Entry<Customer>(existingCustomer).State = EntityState.Deleted;
}
}
public Customer GetById(int customerId)
{
return dbContext.Customers.Include("Addresses").AsNoTracking().SingleOrDefault(c => c.CustomerId == customerId);
}
public IList<Customer> GetPagedAndSorted(int pageNumber, int pageSize, string sortBy, SortDirection sortDirection)
{
return null;
}
public void Save()
{
dbContext.SaveChanges();
}
#endregion CoreMethods
#region AdditionalMethods
#endregion AdditionalMethods
}
}