我有一个Web API项目,它引用了我的模型和DAL程序集.向用户呈现登录屏幕,他可以在其中选择不同的数据库.
我按如下方式构建连接字符串:
public void Connect(Database database)
{
//Build an SQL connection string
SqlConnectionStringBuilder sqlString = new SqlConnectionStringBuilder()
{
DataSource = database.Server,
InitialCatalog = database.Catalog,
UserID = database.Username,
Password = database.Password,
};
//Build an entity framework connection string
EntityConnectionStringBuilder entityString = new EntityConnectionStringBuilder()
{
Provider = database.Provider,
Metadata = Settings.Default.Metadata,
ProviderConnectionString = sqlString.ToString()
};
}
Run Code Online (Sandbox Code Playgroud)
首先,我如何实际更改数据上下文的连接?
其次,由于这是一个Web API项目,连接字符串(在每个登录时设置)在整个用户的交互中是持久的还是应该每次都传递到我的数据上下文?
作为实体框架的新手,我真的很痴迷于如何处理这一系列问题.在我目前正在进行的项目中,整个站点与EF模型高度集成.首先,使用依赖注入引导程序控制对EF上下文的访问.出于操作原因,我们无法使用DI库.我删除了它并在需要时使用了上下文对象的各个实例的模型.我开始得到以下异常:
"XXX"类型已多次映射.
我们得出结论,背景的不同实例导致了这个问题.然后,我将上下文对象抽象为一个静态实例,每个线程/页面都访问该实例.我现在得到关于交易的几个例外之一:
不允许新事务,因为会话中正在运行其他线程.
无法执行事务操作,因为存在处理此事务的待处理请求.
当分配给命令的连接处于挂起的本地事务中时,ExecuteReader要求该命令具有事务.该命令的Transaction属性尚未初始化.
最后一个异常发生在加载操作上.我没有尝试将上下文状态保存回失败的线程上的Db.然而,有另一个线程执行这样的操作.
这些例外情况最多是间歇性的,但我设法让网站进入一个由于事务锁定而拒绝新连接的状态.不幸的是我找不到异常细节.
我想我的第一个问题是,EF模型是否应该从静态单个实例中使用?此外,是否可以消除EF中的交易需求?我试过使用一个TransactionScope没有成功的对象......
说实话,我在这里很多,并且无法理解为什么(应该是什么)相当简单的操作导致这样的问题......
我需要在我的Startup类中实例化的Singleton类中访问我的数据库.似乎直接注入它会导致处理掉的DbContext.
我收到以下错误:
无法访问已处置的对象.对象名称:'MyDbContext'.
我的问题有两个:为什么这不起作用,如何在单例类实例中访问我的数据库?
这是我的Startup类中的ConfigureServices方法:
public void ConfigureServices(IServiceCollection services)
{
// code removed for brevity
services.AddEntityFramework().AddSqlServer().AddDbContext<MyDbContext>(
options =>
{
var config = Configuration["Data:DefaultConnection:ConnectionString"];
options.UseSqlServer(config);
});
// code removed for brevity
services.AddSingleton<FunClass>();
}
Run Code Online (Sandbox Code Playgroud)
这是我的控制器类:
public class TestController : Controller
{
private FunClass _fun;
public TestController(FunClass fun)
{
_fun = fun;
}
public List<string> Index()
{
return _fun.GetUsers();
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的FunClass:
public class FunClass
{
private MyDbContext db;
public FunClass(MyDbContext ctx) {
db = ctx;
}
public List<string> GetUsers()
{
var lst …Run Code Online (Sandbox Code Playgroud) 我正在使用StructureMap来解析对我的存储库类的引用.我的存储库接口实现了IDisposable,例如
public interface IMyRepository : IDisposable
{
SomeClass GetById(int id);
}
Run Code Online (Sandbox Code Playgroud)
使用Entity Framework实现接口:
public MyRepository : IMyRepository
{
private MyDbContext _dbContext;
public MyDbContext()
{
_dbContext = new MyDbContext();
}
public SomeClass GetById(int id)
{
var query = from x in _dbContext
where x.Id = id
select x;
return x.FirstOrDefault();
}
public void Dispose()
{
_dbContext.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
无论如何提到我正在使用StructureMap来解析IMyRepository.那么何时,何地以及如何调用我的处理方法?
我正在创建一个Web Api应用程序,我想使用承载令牌进行用户身份验证.我实现了令牌逻辑,按照这篇文章,一切似乎都运行正常.注意:我没有使用ASP.NET身份提供程序.相反,我为它创建了一个自定义用户实体和服务.
public class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureOAuth(app);
var config = new HttpConfiguration();
var container = DependancyConfig.Register();
var dependencyResolver = new AutofacWebApiDependencyResolver(container);
config.DependencyResolver = dependencyResolver;
app.UseAutofacMiddleware(container);
app.UseAutofacWebApi(config);
WebApiConfig.Register(config);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(config);
}
public void ConfigureOAuth(IAppBuilder app)
{
var oAuthServerOptions = new OAuthAuthorizationServerOptions
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
Provider = new SimpleAuthorizationServerProvider()
};
// Token Generation
app.UseOAuthAuthorizationServer(oAuthServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
}
}
Run Code Online (Sandbox Code Playgroud)
这是我对SimpleAuthorizationServerProvider类的实现
private IUserService _userService;
public IUserService UserService
{
get …Run Code Online (Sandbox Code Playgroud) dependency-injection autofac owin asp.net-web-api2 bearer-token
所有,
有很多关于Unity Lifetime Managers的帖子,但是我还没有发现有人说"在这些情况下你应该总是使用X"这是一个很好的经验法则.让我描述一下我的应用程序,我有一个ASP.NET MVC 4 Web应用程序.我有一个包含3个项目的Visual Studio解决方案,我的'Core'项目,包含我的所有EF内容,测试项目和MVC Web项目.我使用Unity进行依赖注入,现在有以下代码:
// Context
container.RegisterType<IDatabaseFactory, DatabaseFactory>(
new ContainerControlledLifetimeManager();
container.RegisterType<UnitOfWork>(
new ContainerControlledLifetimeManager());
Run Code Online (Sandbox Code Playgroud)
但是,我注意到我的上下文没有重新创建每个新的Web请求,这是我认为我想要的(如果我在这个假设中错了,请告诉我).我很难分析下面列出的网站中的所有信息,并且已经阅读了很多人创建自己的名为PerHttpRequestLifetimeManager的类来处理这个问题.
这里最好的做法是什么?
entity-framework dependency-injection unity-container httprequest asp.net-mvc-4
我正在尝试在我的Windows窗体应用程序中实现IoC.我的选择落在Simple Injector上,因为它快速而轻巧.我还在我的应用程序中实现了工作单元和存储库模式.这是结构:
DbContext:
public class MemberContext : DbContext
{
public MemberContext()
: base("Name=MemberContext")
{ }
public DbSet<Member> Members { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();\
}
}
Run Code Online (Sandbox Code Playgroud)
型号:
public class Member
{
public int MemberID { get; set; }
public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
GenericRepository:
public abstract class GenericRepository<TEntity> : IGenericRepository<TEntity>
where TEntity : class
{
internal DbContext context;
internal DbSet<TEntity> dbSet;
public GenericRepository(DbContext context)
{
this.context = context; …Run Code Online (Sandbox Code Playgroud) c# entity-framework inversion-of-control repository-pattern simple-injector
我对哪种方式更好以及使用哪种方式感到困惑.当然,如果你总能得到HttpContext.GetOwinContext().Get() ; 那为什么甚至创建一个新的ApplicationDbContext并冒险加倍对象等?
注意:我在这里专门谈论Web应用程序.
我在ASP.NET应用程序(使用Entity Framework)中使用MVC模式的方式如下:
1)我的Models文件夹包含所有EF实体以及我的ViewModel
2)我有一个Helpers文件夹,我存储为特定应用程序创建的类.
3)在我的Helpers文件夹中,我有一个名为的静态类MyHelper,其中包含使用EF访问数据库的方法.
namespace myApp.Helpers
{
public static class MyHelper
{
public static async Task<ProductVM> GetProductAsync(int productId)
{
using (var context = new myEntities())
{
return await context.vwxProducts.Where(x => x.ProductId == productId).Select(x => new ProductVM { A = x.A, B = x.B }).FirstOrDefaultAsync();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
4)我的控制器然后在必要时调用这些函数:
namespace myApp.Controllers
{
public class ProductController : Controller
{
[HttpGet]
public async Task<ActionResult> Index(int productId)
{
var productVM = await MyHelper.GetProductAsync(productId);
return …Run Code Online (Sandbox Code Playgroud) 我有一个使用razor进行服务器端渲染的页面,您可以在其中添加来自不同列表的几个元素,填写一些字段并在提交时从中创建请求.
每次从任何列表添加/获取项目时,我都会将具有提交按钮的帖子发送到特定操作,例如"CustomerSelected".我这样做,因为我需要为添加的项重新创建其他视图组件.在这些方法中,我想将添加的对象添加到db上下文中,因此在提交时我可以说SaveChanges(),而不必在同一方法中组装所有内容.但在.net核心数据库上下文是每个请求,建议保持这种方式.在这种情况下,我如何在请求之间存储这些临时实体对象,以后如果有人决定提交它们,我可以说SaveChanges()或丢弃它们?
我想要这样的东西:
public IActionResult CustomerAdded(int customerId)
{
var customer = _context.Customers.First(c => c.IdCustomer == customerId);
var message = _context.Messages.First(m => m.IdMessage = _idMessage);
message.Customers.Add(customer);
return View();
}
public IActionResult ItemAdded(int itemId)
{
var item = _context.Items.First(c => c.IdItem == itemId);
var message = _context.Messages.First(m => m.IdMessage = _idMessage);
message.Items.Add(item);
return View();
}
public IActionResult Submit()
{
_context.SaveChanges();
return View();
}
Run Code Online (Sandbox Code Playgroud)
如果这是不可能的,那么我正在考虑在每个方法中添加单个元素并将它们保存在那里并在提交时我将构建最后的最终元素.但如果有人在没有提交的情况下关闭浏览器,那么我的数据库中存在不完整的数据.我必须运行某种工作来删除它们,这对于这么简单的任务来说似乎太过分了.
c# dbcontext entity-framework-core asp.net-core-mvc asp.net-core
c# ×6
asp.net-core ×2
asp.net-mvc ×2
.net ×1
asp.net ×1
autofac ×1
bearer-token ×1
dbcontext ×1
dispose ×1
httprequest ×1
owin ×1
structuremap ×1